am 48f4db19: (-s ours) am ba19ec5b: Import revised translations. DO NOT MERGE
* commit '48f4db19cbc0a5d8fd11c70356667da06e1e4277':
Import revised translations. DO NOT MERGE
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0f6cb13..00354a4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -197,6 +197,12 @@
<receiver
android:name=".widget.BookmarkWidgetProxy"
android:exported="false" />
+ <activity android:name=".widget.BookmarkWidgetConfigure"
+ android:theme="@android:style/Theme.Holo.DialogWhenLarge">
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
+ </intent-filter>
+ </activity>
<!-- Makes .BrowserActivity the search target for any activity in Browser -->
<meta-data android:name="android.app.default_searchable" android:value=".BrowserActivity" />
@@ -208,11 +214,6 @@
This value signifies to the RLZ client that this application uses RLZ tracking. -->
<meta-data android:name="com.google.android.partnersetup.RLZ_ACCESS_POINT"
android:value="@string/rlz_access_point" />
- <receiver android:name=".RlzReceiver">
- <intent-filter>
- <action android:name="android.intent.action.RLZ_VALUES_UPDATED"/>
- </intent-filter>
- </receiver>
<receiver android:name=".OpenDownloadReceiver">
<intent-filter>
@@ -227,11 +228,6 @@
android:readPermission="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
android:exported="false" />
- <receiver android:name=".AccountsChangedReceiver">
- <intent-filter>
- <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
- </intent-filter>
- </receiver>
</application>
</manifest>
diff --git a/res/drawable-hdpi/bg_bookmark_widget_holo.9.png b/res/drawable-hdpi/bg_bookmark_widget_holo.9.png
deleted file mode 100644
index adb57a4..0000000
--- a/res/drawable-hdpi/bg_bookmark_widget_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/bg_bookmarks_widget_holo.9.png b/res/drawable-hdpi/bg_bookmarks_widget_holo.9.png
new file mode 100644
index 0000000..4fd263f
--- /dev/null
+++ b/res/drawable-hdpi/bg_bookmarks_widget_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/browser_widget_preview.png b/res/drawable-hdpi/browser_widget_preview.png
new file mode 100644
index 0000000..4ee806b
--- /dev/null
+++ b/res/drawable-hdpi/browser_widget_preview.png
Binary files differ
diff --git a/res/drawable-hdpi/browsertab_add_focused.png b/res/drawable-hdpi/browsertab_add_focused.png
new file mode 100644
index 0000000..1490a61
--- /dev/null
+++ b/res/drawable-hdpi/browsertab_add_focused.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_ic_back_bookmark_widget_holo_dark.png b/res/drawable-hdpi/btn_ic_back_bookmark_widget_holo_dark.png
deleted file mode 100644
index 5f975e5..0000000
--- a/res/drawable-hdpi/btn_ic_back_bookmark_widget_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png b/res/drawable-hdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png
deleted file mode 100644
index 722f3b8..0000000
--- a/res/drawable-hdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/crumb_divider.9.png b/res/drawable-hdpi/crumb_divider.9.png
deleted file mode 100644
index f748ffa..0000000
--- a/res/drawable-hdpi/crumb_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_browser_bookmark_widget_holo.png b/res/drawable-hdpi/ic_browser_bookmark_widget_holo.png
deleted file mode 100644
index e583acd..0000000
--- a/res/drawable-hdpi/ic_browser_bookmark_widget_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_copy.png b/res/drawable-hdpi/ic_btn_copy.png
deleted file mode 100644
index 847cf7e..0000000
--- a/res/drawable-hdpi/ic_btn_copy.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_find.png b/res/drawable-hdpi/ic_btn_find.png
deleted file mode 100644
index 0da38a1..0000000
--- a/res/drawable-hdpi/ic_btn_find.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_select_all.png b/res/drawable-hdpi/ic_btn_select_all.png
deleted file mode 100644
index 9545a53..0000000
--- a/res/drawable-hdpi/ic_btn_select_all.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_stop_v2.png b/res/drawable-hdpi/ic_btn_stop_v2.png
deleted file mode 100644
index 2c97223..0000000
--- a/res/drawable-hdpi/ic_btn_stop_v2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_clear_search.png b/res/drawable-hdpi/ic_clear_search.png
deleted file mode 100644
index e8e67b4..0000000
--- a/res/drawable-hdpi/ic_clear_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_history_holo_dark.png b/res/drawable-hdpi/ic_history_holo_dark.png
deleted file mode 100644
index 7972a81..0000000
--- a/res/drawable-hdpi/ic_history_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_info_holo_dark.png b/res/drawable-hdpi/ic_home_info_holo_dark.png
new file mode 100644
index 0000000..02df4e1
--- /dev/null
+++ b/res/drawable-hdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_most_visited_holo_dark.png b/res/drawable-hdpi/ic_most_visited_holo_dark.png
deleted file mode 100644
index bbb0bf6..0000000
--- a/res/drawable-hdpi/ic_most_visited_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_new_incognito_holo_dark.png b/res/drawable-hdpi/ic_new_incognito_holo_dark.png
new file mode 100644
index 0000000..dbd2c3c
--- /dev/null
+++ b/res/drawable-hdpi/ic_new_incognito_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_back.png b/res/drawable-hdpi/ic_pie_back.png
deleted file mode 100644
index 32b3ea7..0000000
--- a/res/drawable-hdpi/ic_pie_back.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_bookmarks.png b/res/drawable-hdpi/ic_pie_bookmarks.png
deleted file mode 100644
index 2536856..0000000
--- a/res/drawable-hdpi/ic_pie_bookmarks.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_close_tab.png b/res/drawable-hdpi/ic_pie_close_tab.png
deleted file mode 100644
index 108f8da..0000000
--- a/res/drawable-hdpi/ic_pie_close_tab.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_forward.png b/res/drawable-hdpi/ic_pie_forward.png
deleted file mode 100644
index 4e5f08e..0000000
--- a/res/drawable-hdpi/ic_pie_forward.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_more.png b/res/drawable-hdpi/ic_pie_more.png
deleted file mode 100644
index 0833ee2..0000000
--- a/res/drawable-hdpi/ic_pie_more.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_new_tab.png b/res/drawable-hdpi/ic_pie_new_tab.png
deleted file mode 100644
index 18f49ef..0000000
--- a/res/drawable-hdpi/ic_pie_new_tab.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_refresh.png b/res/drawable-hdpi/ic_pie_refresh.png
deleted file mode 100644
index f0a5d7a..0000000
--- a/res/drawable-hdpi/ic_pie_refresh.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_search.png b/res/drawable-hdpi/ic_pie_search.png
deleted file mode 100644
index f1c8825..0000000
--- a/res/drawable-hdpi/ic_pie_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pie_tabs.png b/res/drawable-hdpi/ic_pie_tabs.png
deleted file mode 100644
index b941285..0000000
--- a/res/drawable-hdpi/ic_pie_tabs.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_thumbnail_view_holo_dark.png b/res/drawable-hdpi/ic_thumbnail_view_holo_dark.png
new file mode 100644
index 0000000..514b7dc
--- /dev/null
+++ b/res/drawable-hdpi/ic_thumbnail_view_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/list_divider_vert.9.png b/res/drawable-hdpi/list_divider_vert.9.png
deleted file mode 100644
index d99730a..0000000
--- a/res/drawable-hdpi/list_divider_vert.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/nav_tab_bg.9.png b/res/drawable-hdpi/nav_tab_bg.9.png
new file mode 100644
index 0000000..2578e4a
--- /dev/null
+++ b/res/drawable-hdpi/nav_tab_bg.9.png
Binary files differ
diff --git a/res/drawable-hdpi/page_indicator.png b/res/drawable-hdpi/page_indicator.png
deleted file mode 100644
index d00b900..0000000
--- a/res/drawable-hdpi/page_indicator.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/page_indicator_unselected2.png b/res/drawable-hdpi/page_indicator_unselected2.png
deleted file mode 100644
index a34fd2e..0000000
--- a/res/drawable-hdpi/page_indicator_unselected2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/progress.9.png b/res/drawable-hdpi/progress.9.png
index 398bee4..2bfc699 100644
--- a/res/drawable-hdpi/progress.9.png
+++ b/res/drawable-hdpi/progress.9.png
Binary files differ
diff --git a/res/drawable-hdpi/qc_background_normal.png b/res/drawable-hdpi/qc_background_normal.png
new file mode 100644
index 0000000..fec04f2
--- /dev/null
+++ b/res/drawable-hdpi/qc_background_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/search_plate_browser.9.png b/res/drawable-hdpi/search_plate_browser.9.png
deleted file mode 100644
index cf0567b..0000000
--- a/res/drawable-hdpi/search_plate_browser.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_nr.png b/res/drawable-hdpi/tab_nr.png
new file mode 100644
index 0000000..d9e74d5
--- /dev/null
+++ b/res/drawable-hdpi/tab_nr.png
Binary files differ
diff --git a/res/drawable-hdpi/text_field_results.9.png b/res/drawable-hdpi/text_field_results.9.png
deleted file mode 100644
index bd4bcc5..0000000
--- a/res/drawable-hdpi/text_field_results.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/thumbnail_bookmarks_widget_no_bookmark_holo.png b/res/drawable-hdpi/thumbnail_bookmarks_widget_no_bookmark_holo.png
new file mode 100644
index 0000000..9d55e98
--- /dev/null
+++ b/res/drawable-hdpi/thumbnail_bookmarks_widget_no_bookmark_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/url_bg_active.9.png b/res/drawable-hdpi/url_bg_active.9.png
new file mode 100644
index 0000000..479acb1
--- /dev/null
+++ b/res/drawable-hdpi/url_bg_active.9.png
Binary files differ
diff --git a/res/drawable-hdpi/url_bg_default.9.png b/res/drawable-hdpi/url_bg_default.9.png
new file mode 100644
index 0000000..7db9db4
--- /dev/null
+++ b/res/drawable-hdpi/url_bg_default.9.png
Binary files differ
diff --git a/res/drawable-hdpi/urlbar_bg.9.png b/res/drawable-hdpi/urlbar_bg.9.png
deleted file mode 100644
index c35383e..0000000
--- a/res/drawable-hdpi/urlbar_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/bg_bookmark_widget_holo.9.png b/res/drawable-mdpi/bg_bookmark_widget_holo.9.png
deleted file mode 100644
index d95f8d3..0000000
--- a/res/drawable-mdpi/bg_bookmark_widget_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/browser_widget_preview.png b/res/drawable-mdpi/browser_widget_preview.png
similarity index 100%
rename from res/drawable/browser_widget_preview.png
rename to res/drawable-mdpi/browser_widget_preview.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_ic_back_bookmark_widget_holo_dark.png b/res/drawable-mdpi/btn_ic_back_bookmark_widget_holo_dark.png
deleted file mode 100644
index d8697b8..0000000
--- a/res/drawable-mdpi/btn_ic_back_bookmark_widget_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png b/res/drawable-mdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png
deleted file mode 100644
index 21a2cc3..0000000
--- a/res/drawable-mdpi/btn_ic_bookmark_bookmark_widget_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/crumb_divider.9.png b/res/drawable-mdpi/crumb_divider.9.png
deleted file mode 100644
index 8c8fd43..0000000
--- a/res/drawable-mdpi/crumb_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/help_useragent_laptop.png b/res/drawable-mdpi/help_useragent_laptop.png
new file mode 100644
index 0000000..59aa721
--- /dev/null
+++ b/res/drawable-mdpi/help_useragent_laptop.png
Binary files differ
diff --git a/res/drawable-mdpi/help_useragent_tablet.png b/res/drawable-mdpi/help_useragent_tablet.png
new file mode 100644
index 0000000..7b579cd
--- /dev/null
+++ b/res/drawable-mdpi/help_useragent_tablet.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_browser_bookmark_widget_holo.png b/res/drawable-mdpi/ic_browser_bookmark_widget_holo.png
deleted file mode 100644
index 0d9e49d..0000000
--- a/res/drawable-mdpi/ic_browser_bookmark_widget_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_copy.png b/res/drawable-mdpi/ic_btn_copy.png
deleted file mode 100644
index 2174368..0000000
--- a/res/drawable-mdpi/ic_btn_copy.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_find.png b/res/drawable-mdpi/ic_btn_find.png
deleted file mode 100644
index 71bc61a..0000000
--- a/res/drawable-mdpi/ic_btn_find.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_select_all.png b/res/drawable-mdpi/ic_btn_select_all.png
deleted file mode 100644
index 8ce8c8f..0000000
--- a/res/drawable-mdpi/ic_btn_select_all.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_stop_v2.png b/res/drawable-mdpi/ic_btn_stop_v2.png
deleted file mode 100644
index 89f01e7..0000000
--- a/res/drawable-mdpi/ic_btn_stop_v2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_clear_search.png b/res/drawable-mdpi/ic_clear_search.png
deleted file mode 100644
index e8e67b4..0000000
--- a/res/drawable-mdpi/ic_clear_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_history_holo_dark.png b/res/drawable-mdpi/ic_history_holo_dark.png
deleted file mode 100644
index 44f2245..0000000
--- a/res/drawable-mdpi/ic_history_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_info_holo_dark.png b/res/drawable-mdpi/ic_home_info_holo_dark.png
new file mode 100644
index 0000000..c34f443
--- /dev/null
+++ b/res/drawable-mdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_most_visited_holo_dark.png b/res/drawable-mdpi/ic_most_visited_holo_dark.png
deleted file mode 100644
index 52082bd..0000000
--- a/res/drawable-mdpi/ic_most_visited_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_back.png b/res/drawable-mdpi/ic_pie_back.png
deleted file mode 100644
index daddaea..0000000
--- a/res/drawable-mdpi/ic_pie_back.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_bookmarks.png b/res/drawable-mdpi/ic_pie_bookmarks.png
deleted file mode 100644
index ffa430d..0000000
--- a/res/drawable-mdpi/ic_pie_bookmarks.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_close_tab.png b/res/drawable-mdpi/ic_pie_close_tab.png
deleted file mode 100644
index 62396f4..0000000
--- a/res/drawable-mdpi/ic_pie_close_tab.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_forward.png b/res/drawable-mdpi/ic_pie_forward.png
deleted file mode 100644
index bd8dcac..0000000
--- a/res/drawable-mdpi/ic_pie_forward.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_more.png b/res/drawable-mdpi/ic_pie_more.png
deleted file mode 100644
index c96c6a4..0000000
--- a/res/drawable-mdpi/ic_pie_more.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_new_tab.png b/res/drawable-mdpi/ic_pie_new_tab.png
deleted file mode 100644
index 206675a..0000000
--- a/res/drawable-mdpi/ic_pie_new_tab.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_refresh.png b/res/drawable-mdpi/ic_pie_refresh.png
deleted file mode 100644
index 5980f8b..0000000
--- a/res/drawable-mdpi/ic_pie_refresh.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_search.png b/res/drawable-mdpi/ic_pie_search.png
deleted file mode 100644
index 6981697..0000000
--- a/res/drawable-mdpi/ic_pie_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_tabs.png b/res/drawable-mdpi/ic_pie_tabs.png
deleted file mode 100644
index fda262a..0000000
--- a/res/drawable-mdpi/ic_pie_tabs.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pie_web.png b/res/drawable-mdpi/ic_pie_web.png
deleted file mode 100644
index 86e41ff..0000000
--- a/res/drawable-mdpi/ic_pie_web.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_thumbnail_view_holo_dark.png b/res/drawable-mdpi/ic_thumbnail_view_holo_dark.png
new file mode 100644
index 0000000..95c674d
--- /dev/null
+++ b/res/drawable-mdpi/ic_thumbnail_view_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_ua_android.png b/res/drawable-mdpi/ic_ua_android.png
new file mode 100644
index 0000000..4f7aa45
--- /dev/null
+++ b/res/drawable-mdpi/ic_ua_android.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_ua_desktop.png b/res/drawable-mdpi/ic_ua_desktop.png
new file mode 100644
index 0000000..4e2f5c2
--- /dev/null
+++ b/res/drawable-mdpi/ic_ua_desktop.png
Binary files differ
diff --git a/res/drawable-mdpi/list_divider_vert.9.png b/res/drawable-mdpi/list_divider_vert.9.png
deleted file mode 100644
index d99730a..0000000
--- a/res/drawable-mdpi/list_divider_vert.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/page_indicator.png b/res/drawable-mdpi/page_indicator.png
deleted file mode 100644
index 73c030a..0000000
--- a/res/drawable-mdpi/page_indicator.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/page_indicator_unselected2.png b/res/drawable-mdpi/page_indicator_unselected2.png
deleted file mode 100644
index 70818ee..0000000
--- a/res/drawable-mdpi/page_indicator_unselected2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/search_plate_browser.9.png b/res/drawable-mdpi/search_plate_browser.9.png
deleted file mode 100644
index 2370d9c..0000000
--- a/res/drawable-mdpi/search_plate_browser.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/text_field_results.9.png b/res/drawable-mdpi/text_field_results.9.png
deleted file mode 100644
index 167c42d..0000000
--- a/res/drawable-mdpi/text_field_results.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/urlbar_bg.9.png b/res/drawable-mdpi/urlbar_bg.9.png
deleted file mode 100644
index 18b49e7..0000000
--- a/res/drawable-mdpi/urlbar_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/bookmark_thumb_selector.xml b/res/drawable/bookmark_thumb_selector.xml
index d4a12a3..5509aba 100644
--- a/res/drawable/bookmark_thumb_selector.xml
+++ b/res/drawable/bookmark_thumb_selector.xml
@@ -14,8 +14,7 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/bookmarks_widget_thumb_selector_focused" />
<item android:state_pressed="true" android:drawable="@drawable/bookmark_thumb_selector_transition" />
<item android:drawable="@android:color/transparent" />
diff --git a/res/drawable/navtab_close_background.xml b/res/drawable/navtab_close_background.xml
new file mode 100644
index 0000000..e20cc5c
--- /dev/null
+++ b/res/drawable/navtab_close_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/bookmarks_widget_thumb_selector_focused" />
+ <item android:state_pressed="true" android:drawable="@drawable/bookmark_thumb_selector_transition" />
+ <item android:drawable="@color/navtab_bg" />
+</selector>
+
diff --git a/res/layout-sw600dp/browser_add_bookmark.xml b/res/drawable/url_selector.xml
similarity index 69%
copy from res/layout-sw600dp/browser_add_bookmark.xml
copy to res/drawable/url_selector.xml
index 14edecf..d4febe6 100644
--- a/res/layout-sw600dp/browser_add_bookmark.xml
+++ b/res/drawable/url_selector.xml
@@ -14,12 +14,12 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/add_bookmark_width"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
-
- <include layout="@layout/browser_add_bookmark_content" />
-
-</LinearLayout>
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/url_bg_active" />
+ <item
+ android:state_focused="false"
+ android:drawable="@drawable/url_bg_default" />
+</selector>
\ No newline at end of file
diff --git a/res/layout-land/nav_screen.xml b/res/layout-land/nav_screen.xml
new file mode 100644
index 0000000..e4eb800
--- /dev/null
+++ b/res/layout-land/nav_screen.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/nav_screen"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ <LinearLayout
+ android:id="@+id/tabbar"
+ android:orientation="vertical"
+ android:layout_width="44dip"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:background="#80404040">
+ <ImageButton
+ android:id="@+id/newtab"
+ android:layout_height="0dip"
+ android:layout_weight="0.25"
+ android:layout_width="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_new_window_holo_dark" />
+ <ImageButton
+ android:id="@+id/newincognito"
+ android:layout_height="0dip"
+ android:layout_weight="0.25"
+ android:layout_width="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_new_incognito_holo_dark" />
+ <ImageButton
+ android:id="@+id/bookmarks"
+ android:layout_height="0dip"
+ android:layout_weight="0.25"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_bookmarks_history_holo_dark"
+ style="@style/HoloButton" />
+ <ImageButton
+ android:id="@+id/more"
+ android:layout_height="0dip"
+ android:layout_weight="0.25"
+ android:layout_width="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@*android:drawable/ic_menu_moreoverflow_normal_holo_dark" />
+ </LinearLayout>
+ <com.android.browser.NavTabScroller
+ android:id="@+id/scroller"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_toLeftOf="@id/tabbar" />
+</RelativeLayout>
diff --git a/res/layout-sw600dp/browser_add_bookmark.xml b/res/layout-xlarge/bookmarks_history.xml
similarity index 69%
copy from res/layout-sw600dp/browser_add_bookmark.xml
copy to res/layout-xlarge/bookmarks_history.xml
index 14edecf..ae5e19b 100644
--- a/res/layout-sw600dp/browser_add_bookmark.xml
+++ b/res/layout-xlarge/bookmarks_history.xml
@@ -13,13 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/add_bookmark_width"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
-
- <include layout="@layout/browser_add_bookmark_content" />
-
-</LinearLayout>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/bg_browser" />
diff --git a/res/layout-xlarge/history.xml b/res/layout-xlarge/history.xml
new file mode 100644
index 0000000..2d949e1
--- /dev/null
+++ b/res/layout-xlarge/history.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+>
+
+ <ViewStub
+ android:id="@+id/pref_stub"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:inflatedId="@+id/history" />
+
+ <TextView android:id="@android:id/empty"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="@string/empty_history"
+ android:visibility="gone"
+ />
+
+</FrameLayout>
diff --git a/res/layout/active_tabs.xml b/res/layout/active_tabs.xml
index 8b5fe9e..f9bd6b0 100644
--- a/res/layout/active_tabs.xml
+++ b/res/layout/active_tabs.xml
@@ -14,31 +14,41 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:background="@color/black"
- >
- <RelativeLayout
- style="?android:attr/windowTitleBackgroundStyle"
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/new_tab"
+ android:text="@string/new_tab"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <Button
+ android:id="@+id/new_incognito_tab"
+ android:text="@string/new_incognito_tab"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:paddingLeft="0dip"
+ android:paddingRight="0dip" />
+
+ </LinearLayout>
+
+ <ListView
+ android:id="@android:id/list"
android:layout_width="match_parent"
- android:layout_height="?android:attr/windowTitleSize"
- >
- <TextView android:id="@android:id/title"
- style="?android:attr/windowTitleStyle"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- android:fadingEdge="horizontal"
- android:gravity="center_vertical"
- android:text="@string/active_tabs"
- />
- </RelativeLayout>
- <ListView android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:cacheColorHint="@color/black"
- />
-</LinearLayout>
+ android:layout_height="match_parent"
+ android:listSelector="@drawable/bookmark_thumb_selector"
+ android:drawSelectorOnTop="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true" />
+
+</merge>
diff --git a/res/layout-sw600dp/browser_add_bookmark.xml b/res/layout/bookmark_grid_row.xml
similarity index 71%
rename from res/layout-sw600dp/browser_add_bookmark.xml
rename to res/layout/bookmark_grid_row.xml
index 14edecf..5dc3a76 100644
--- a/res/layout-sw600dp/browser_add_bookmark.xml
+++ b/res/layout/bookmark_grid_row.xml
@@ -14,12 +14,11 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/add_bookmark_width"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
-
- <include layout="@layout/browser_add_bookmark_content" />
-
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/combo_rowPadding"
+ android:paddingRight="@dimen/combo_rowPadding">
</LinearLayout>
+
diff --git a/res/layout/bookmark_group_view.xml b/res/layout/bookmark_group_view.xml
new file mode 100644
index 0000000..e6c9628
--- /dev/null
+++ b/res/layout/bookmark_group_view.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:background="?android:attr/listChoiceBackgroundIndicator">
+
+ <TextView
+ android:id="@+id/group_name"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingLeft="50dp"
+ android:gravity="center_vertical" />
+
+ <FrameLayout
+ android:id="@+id/crumb_holder"
+ android:paddingLeft="16dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
diff --git a/res/layout/bookmark_thumbnail.xml b/res/layout/bookmark_thumbnail.xml
index c545fa4..cd7b9be 100644
--- a/res/layout/bookmark_thumbnail.xml
+++ b/res/layout/bookmark_thumbnail.xml
@@ -14,11 +14,12 @@
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+<com.android.browser.view.BookmarkContainer xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:orientation="vertical"
- android:padding="0dip"
+ android:padding="@dimen/combo_horizontalSpacing"
+ android:background="@drawable/bookmark_thumb_selector"
>
<ImageView
@@ -59,4 +60,4 @@
android:textColor="#AAAAAA"
/>
-</RelativeLayout>
+</com.android.browser.view.BookmarkContainer>
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index 81327e4..bcabc03 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -33,20 +33,14 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
- <GridView
+ <com.android.browser.view.BookmarkExpandableGridView
android:id="@+id/grid"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
- android:horizontalSpacing="@dimen/combo_horizontalSpacing"
- android:verticalSpacing="40dip"
- android:scrollbarStyle="insideInset"
- android:listSelector="@drawable/bookmark_thumb_selector"
- android:drawSelectorOnTop="true"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:numColumns="auto_fit"
- android:stretchMode="spacingWidth" />
+ android:childDivider="@android:color/transparent"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="0dp" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
diff --git a/res/layout/bookmarks_drag_actionmode.xml b/res/layout/bookmarks_drag_actionmode.xml
new file mode 100644
index 0000000..64b1042
--- /dev/null
+++ b/res/layout/bookmarks_drag_actionmode.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:divider="?android:attr/dividerVertical"
+ android:dividerPadding="12dp"
+ android:showDividers="middle"
+ android:gravity="right"
+ android:minHeight="?android:attr/actionBarSize">
+ <ImageView
+ android:id="@+id/open_context_menu_id"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:src="@drawable/ic_web_holo_dark" />
+ <ImageView
+ android:id="@+id/new_window_context_menu_id"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:src="@drawable/ic_new_window_holo_dark" />
+ <ImageView
+ android:id="@+id/info"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:src="@drawable/ic_home_info_holo_dark" />
+</LinearLayout>
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
index 5622917..826fe49 100644
--- a/res/layout/bookmarks_history.xml
+++ b/res/layout/bookmarks_history.xml
@@ -4,9 +4,9 @@
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.
@@ -18,4 +18,5 @@
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/bg_browser" />
+ android:background="@drawable/bg_browser"
+ android:paddingTop="?android:attr/actionBarSize" />
diff --git a/res/layout/browser_add_bookmark_content.xml b/res/layout/browser_add_bookmark_content.xml
index 6ee7a5a..6287ef8 100644
--- a/res/layout/browser_add_bookmark_content.xml
+++ b/res/layout/browser_add_bookmark_content.xml
@@ -15,51 +15,39 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <RelativeLayout android:id="@+id/crumb_holder"
+ <LinearLayout android:id="@+id/crumb_holder"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical"
+ android:layout_height="?android:attr/listPreferredItemHeight"
android:visibility="gone"
android:paddingLeft="5dip"
android:paddingRight="5dip"
+ android:orientation="horizontal"
>
<com.android.browser.BreadCrumbView android:id="@+id/crumbs"
- android:layout_width="wrap_content"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_alignParentLeft="true"
- android:layout_toLeftOf="@+id/add_divider"
- android:layout_centerVertical="true"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent" />
+ <View android:id="@+id/add_divider"
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:background="?android:attr/dividerVertical"
/>
<TextView
android:id="@+id/add_new_folder"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignBaseline="@+id/crumbs"
+ android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_add_string"
- android:gravity="center_vertical"
android:text="@string/new_folder"
android:visibility="gone"
- android:layout_centerVertical="true"
- android:layout_alignTop="@+id/crumbs"
- android:layout_alignBottom="@+id/crumbs"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
- android:textAppearance="?android:attr/textAppearanceMedium" />
- <ImageView android:id="@+id/add_divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toLeftOf="@+id/add_new_folder"
- android:src="@drawable/crumb_divider"
- android:layout_centerVertical="true"
- />
- </RelativeLayout>
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_vertical" />
+ </LinearLayout>
<LinearLayout android:id="@+id/title_holder"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
- android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="5dip"
android:paddingRight="5dip"
>
@@ -72,12 +60,10 @@
android:drawableLeft="@drawable/ic_bookmark_on_holo_dark"
android:text="@string/bookmark_this_page"
android:textAppearance="?android:attr/textAppearanceMedium" />
- <ImageView android:id="@+id/remove_divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:src="@drawable/crumb_divider"
- android:layout_centerVertical="true"
+ <View android:id="@+id/remove_divider"
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:background="?android:attr/dividerVertical"
android:visibility="gone"
/>
<TextView android:id="@+id/remove"
@@ -90,11 +76,9 @@
android:visibility="gone"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
- <View android:id="@+id/titleDivider"
- android:layout_width="match_parent"
+ <View android:layout_width="match_parent"
android:layout_height="1dip"
- android:gravity="fill_horizontal"
- android:background="?android:attr/colorForeground"
+ android:background="?android:attr/dividerHorizontal"
/>
<TableLayout android:id="@+id/default_view"
@@ -105,12 +89,12 @@
android:paddingTop="10dip"
android:paddingLeft="20dip"
android:paddingRight="20dip" >
- <TableRow>
+ <TableRow android:layout_marginBottom="10dip">
<TextView
android:id="@+id/titleText"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_marginBottom="30dip"
+ android:layout_gravity="center_vertical"
android:text="@string/name"
android:textAppearance="?android:attr/textAppearanceMedium" />
@@ -118,42 +102,54 @@
android:id="@+id/title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_marginRight="20dip"
android:layout_marginLeft="20dip"
- android:gravity="fill_horizontal"
android:inputType="textCapSentences"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium" />
</TableRow>
<TableRow
+ android:layout_marginBottom="10dip"
android:id="@+id/row_address">
<TextView
android:id="@+id/addressText"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical"
android:text="@string/location"
- android:gravity="left"
- android:layout_marginBottom="20dip"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/address"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_marginRight="20dip"
android:layout_marginLeft="20dip"
android:hint="@string/http"
- android:gravity="fill_horizontal"
android:inputType="textUri"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium" />
</TableRow>
- <TableRow>
+ <TableRow android:layout_marginBottom="10dip">
<TextView
- android:id="@+id/add_to"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/account"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <Spinner
+ android:id="@+id/accounts"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginLeft="20dip"
+ android:spinnerMode="dropdown"
+ />
+ </TableRow>
+ <TableRow android:layout_marginBottom="10dip">
+ <TextView
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical"
android:text="@string/containing_folder"
android:textAppearance="?android:attr/textAppearanceMedium" />
@@ -161,10 +157,8 @@
android:id="@+id/folder"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_marginRight="20dip"
android:layout_marginLeft="20dip"
android:spinnerMode="dropdown"
- android:gravity="center_vertical"
/>
</TableRow>
</TableLayout>
diff --git a/res/layout/custom_screen.xml b/res/layout/custom_screen.xml
index 525f30c..2105501 100644
--- a/res/layout/custom_screen.xml
+++ b/res/layout/custom_screen.xml
@@ -37,3 +37,4 @@
/>
</LinearLayout>
</FrameLayout>
+
diff --git a/res/layout/help_dialog_useragent_switcher.xml b/res/layout/help_dialog_useragent_switcher.xml
new file mode 100644
index 0000000..cc29a2d
--- /dev/null
+++ b/res/layout/help_dialog_useragent_switcher.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/help_useragent_switcher" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/help_useragent_tablet" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/help_useragent_laptop" />
+
+</LinearLayout>
diff --git a/res/layout/history.xml b/res/layout/history.xml
index f7d2c7c..f3adb51 100644
--- a/res/layout/history.xml
+++ b/res/layout/history.xml
@@ -19,11 +19,10 @@
android:layout_height="match_parent"
>
- <ViewStub
- android:id="@+id/pref_stub"
+ <ExpandableListView
+ android:id="@+id/history"
android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:inflatedId="@+id/history" />
+ android:layout_width="match_parent" />
<TextView android:id="@android:id/empty"
android:layout_width="wrap_content"
diff --git a/res/layout/history_item.xml b/res/layout/history_item.xml
index 3b3dd7a..f6076a0 100644
--- a/res/layout/history_item.xml
+++ b/res/layout/history_item.xml
@@ -42,7 +42,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:ellipsize="end"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
/>
<TextView android:id="@+id/url"
android:textAppearance="?android:attr/textAppearanceSmall"
@@ -50,7 +51,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:ellipsize="end"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
/>
</LinearLayout>
<CheckBox android:id="@+id/star"
diff --git a/res/layout/tab_view_add_tab.xml b/res/layout/min_font_size.xml
similarity index 62%
rename from res/layout/tab_view_add_tab.xml
rename to res/layout/min_font_size.xml
index f4e0f02..d4d1314 100644
--- a/res/layout/tab_view_add_tab.xml
+++ b/res/layout/min_font_size.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2011 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.
@@ -15,25 +15,24 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_width="match_parent"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- >
- <ImageView
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:src="@drawable/ic_new_window_holo_dark"/>
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingRight="6dip"
+ android:paddingTop="6dip"
+ android:paddingBottom="6dip"
+ android:paddingLeft="8dip">
+
<TextView
- android:layout_width="match_parent"
+ android:text="@string/pref_min_font_size"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end"
- android:text="@string/new_tab"
- />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <SeekBar
+ android:id="@+id/seekbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
</LinearLayout>
+
diff --git a/res/layout/nav_screen.xml b/res/layout/nav_screen.xml
new file mode 100644
index 0000000..667bf08
--- /dev/null
+++ b/res/layout/nav_screen.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/nav_screen"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <LinearLayout
+ android:id="@+id/tabbar"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="44dip"
+ android:layout_alignParentBottom="true"
+ android:background="#80404040">
+ <ImageButton
+ android:id="@+id/newtab"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_new_window_holo_dark" />
+ <ImageButton
+ android:id="@+id/newincognito"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_new_incognito_holo_dark" />
+ <ImageButton
+ android:id="@+id/bookmarks"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_bookmarks_history_holo_dark"
+ style="@style/HoloButton" />
+ <ImageButton
+ android:id="@+id/more"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@*android:drawable/ic_menu_moreoverflow_normal_holo_dark" />
+ </LinearLayout>
+ <com.android.browser.NavTabScroller
+ android:id="@+id/scroller"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@id/tabbar" />
+</RelativeLayout>
diff --git a/res/layout/nav_tab_view.xml b/res/layout/nav_tab_view.xml
new file mode 100644
index 0000000..5a71c71
--- /dev/null
+++ b/res/layout/nav_tab_view.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/main"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:orientation="vertical"
+ android:focusable="false">
+ <LinearLayout
+ android:id="@+id/titlebar"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/toolbar_height"
+ android:layout_gravity="center_horizontal"
+ android:paddingLeft="4dip"
+ android:paddingRight="4dip"
+ android:paddingTop="2dip"
+ android:paddingBottom="2dip">
+ <ImageView
+ android:id="@+id/favicon"
+ android:layout_width="20dip"
+ android:layout_height="20dip"
+ android:layout_marginLeft="4dip"
+ android:layout_marginRight="4dip"
+ android:layout_gravity="center_vertical" />
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1.0"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:lines="1"
+ android:background="@*android:drawable/edit_text_holo_dark"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:scrollHorizontally="true"
+ android:hint="@string/search_hint" />
+ <ImageButton
+ android:id="@+id/refresh"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_refresh_holo_dark"
+ style="@style/HoloButton" />
+ <ImageButton
+ android:id="@+id/forward"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_forward_holo_dark"
+ style="@style/HoloButton" />
+ </LinearLayout>
+ <FrameLayout
+ android:id="@+id/tab_view"
+ android:layout_width="@dimen/nav_tab_width"
+ android:layout_height="@dimen/nav_tab_height"
+ android:layout_gravity="center_horizontal"
+ android:padding="4dip"
+ android:focusable="false"
+ android:background="@drawable/nav_tab_bg">
+ <ImageButton
+ android:id="@+id/closetab"
+ android:src="@drawable/ic_stop_holo_dark"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|right"
+ android:background="@drawable/navtab_close_background" />
+ </FrameLayout>
+</LinearLayout>
diff --git a/res/layout/preference_list_content.xml b/res/layout/preference_list_content.xml
index 0cf0b7e..ad3d64e 100644
--- a/res/layout/preference_list_content.xml
+++ b/res/layout/preference_list_content.xml
@@ -15,11 +15,13 @@
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
+
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
+
<LinearLayout
android:id="@+id/headers"
android:orientation="vertical"
@@ -30,6 +32,7 @@
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
android:layout_weight="10">
+
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0px"
@@ -38,11 +41,14 @@
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
android:scrollbarAlwaysDrawVerticalTrack="true" />
+
<FrameLayout android:id="@+id/list_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
+
</LinearLayout>
+
<LinearLayout
android:id="@+id/prefs_frame"
android:layout_width="0px"
@@ -55,6 +61,7 @@
android:background="?android:attr/detailsElementBackground"
android:orientation="vertical"
android:visibility="gone" >
+
<!-- Breadcrumb inserted here -->
<android.app.FragmentBreadCrumbs
android:id="@android:id/title"
@@ -64,18 +71,22 @@
android:paddingBottom="8dip"
android:gravity="center_vertical|left"
android:layout_marginLeft="48dip"
- android:layout_marginRight="48dip" />
+ android:layout_marginRight="48dip"
+ />
+
<ImageView
android:layout_width="match_parent"
android:layout_height="1dip"
android:paddingLeft="32dip"
android:paddingRight="32dip"
- android:src="#404040" />
+ android:src="#404040"
+ />
<android.preference.PreferenceFrameLayout android:id="@+id/prefs"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
- android:layout_marginTop="-1dip" />
+ android:layout_marginTop="-1dip"
+ />
</LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/tab_view.xml b/res/layout/tab_view.xml
index 885f4cf..8ffb73d 100644
--- a/res/layout/tab_view.xml
+++ b/res/layout/tab_view.xml
@@ -20,42 +20,54 @@
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical"
+ android:paddingLeft="8dip"
+ android:paddingTop="4dip"
+ android:paddingBottom="4dip"
>
- <!-- This ImageView has the same width as the ImageView in
- tab_view_add_tab.xml. -->
- <ImageView android:id="@+id/favicon"
- android:layout_width="20dip"
- android:layout_height="20dip"
- android:layout_marginLeft="18dip"
- android:layout_marginRight="18dip"
- android:background="@drawable/fav_icn_background"
- android:padding="2dip"/>
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/list_item"
android:layout_width="0dip"
- android:layout_height="wrap_content"
android:layout_weight="1"
- android:orientation="vertical"
- >
- <TextView android:id="@+id/title"
+ android:layout_height="wrap_content"
+ android:background="@drawable/bookmark_list_favicon_bg">
+ <ImageView
+ android:id="@+id/thumb"
+ android:src="@drawable/thumbnail_bookmarks_widget_no_bookmark_holo"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/tab_view_thumbnail_height"
+ android:scaleType="fitXY"
+ android:cropToPadding="true" />
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end"
- />
- <TextView android:id="@+id/url"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end"
- />
- </LinearLayout>
+ android:layout_alignBottom="@id/thumb"
+ android:background="@color/tabViewTitleBackground">
+ <ImageView
+ android:id="@+id/favicon"
+ android:src="@drawable/app_web_browser_sm"
+ android:layout_width="@dimen/favicon_size"
+ android:layout_height="@dimen/favicon_size"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="4dip"
+ android:layout_marginRight="8dip"
+ android:layout_marginTop="4dip"
+ android:layout_marginBottom="4dip"
+ android:scaleType="fitXY" />
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textSize="12sp"
+ android:typeface="sans"
+ android:textColor="@android:color/white" />
+ </LinearLayout>
+ </RelativeLayout>
<View android:id="@+id/divider"
- android:background="#ff313431"
- android:layout_width="1dip"
+ android:background="?android:attr/dividerVertical"
+ android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginLeft="8dip"
android:layout_marginTop="5dip"
@@ -64,10 +76,10 @@
<view class="com.android.browser.ActiveTabsPage$CloseHolder" android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingLeft="18dip"
- android:paddingRight="18dip"
- android:background="@drawable/close_background"
- android:src="@drawable/btn_close_window"
+ android:paddingLeft="12dip"
+ android:paddingRight="12dip"
+ android:background="@drawable/bookmark_thumb_selector"
+ android:src="@drawable/ic_close_window_holo_dark"
android:scaleType="center"
/>
</LinearLayout>
diff --git a/res/layout/tab_view_add_incognito_tab.xml b/res/layout/tab_view_add_incognito_tab.xml
deleted file mode 100644
index 43fcb43..0000000
--- a/res/layout/tab_view_add_incognito_tab.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:layout_width="match_parent"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- >
- <ImageView
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:src="@drawable/ic_new_window_holo_dark"/>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end"
- android:text="@string/new_incognito_tab"
- />
-</LinearLayout>
diff --git a/res/layout/title_bar.xml b/res/layout/title_bar.xml
index 99ac04d..649a4a0 100644
--- a/res/layout/title_bar.xml
+++ b/res/layout/title_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright 2009, The Android Open Source Project
+ Copyright 2011, 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.
@@ -14,85 +14,148 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/titlebar"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
+ android:layout_height="wrap_content">
<LinearLayout
+ android:id="@+id/taburlbar"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/toolbar_height"
android:orientation="horizontal"
android:background="@drawable/bg_urlbar"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingTop="2dip"
- android:paddingBottom="1dip"
- >
-
- <LinearLayout android:id="@+id/title_bg"
+ android:paddingBottom="2dip">
+ <LinearLayout
+ android:id="@+id/title_bg"
android:layout_width="0dip"
android:layout_weight="1.0"
- android:layout_height="48dip"
- android:layout_marginBottom="4dip"
+ android:layout_height="match_parent"
android:gravity="center_vertical"
- android:orientation="horizontal"
- android:background="@drawable/url_background"
- >
- <ImageView android:id="@+id/favicon"
- android:layout_width="20dip"
- android:layout_height="20dip"
- />
- <ImageView android:id="@+id/lock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="3dip"
- android:visibility="gone"
- />
- <com.android.browser.UrlInputView
- android:id="@+id/url_input"
- android:focusable="true"
- android:layout_width="0dip"
- android:layout_weight="1.0"
- android:layout_height="match_parent"
- android:layout_marginLeft="3dip"
- android:paddingLeft="0dip"
- android:paddingRight="0dip"
- android:background="@null"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:hint="@string/search_hint"
- android:singleLine="true"
- android:ellipsize="end"
- android:lines="1"
- android:scrollHorizontally="true"
- android:inputType="textUri"
- android:imeOptions="actionGo"
- style="@style/Suggestions" />
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/favicon"
+ android:layout_width="20dip"
+ android:layout_height="20dip" />
+ <ImageView
+ android:id="@+id/lock"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="2dip"
+ android:visibility="gone" />
+ <com.android.browser.UrlInputView
+ android:id="@+id/url"
+ android:focusable="true"
+ android:layout_width="0dip"
+ android:layout_weight="1.0"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="2dip"
+ android:paddingLeft="4dip"
+ android:paddingRight="4dip"
+ android:background="@*android:drawable/edit_text_holo_dark"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:hint="@string/search_hint"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:lines="1"
+ android:scrollHorizontally="true"
+ android:inputType="textUri"
+ android:imeOptions="actionGo"
+ style="@style/Suggestions" />
</LinearLayout>
- <ImageButton
+ <ImageView
+ android:id="@+id/voice"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_voice_search_holo_dark"
+ android:visibility="gone" />
+ <ImageView
android:id="@+id/stop"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- style="@style/HoloButton"
- android:src="@drawable/ic_stop_holo_dark"
- android:visibility="gone"
- />
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:src="@drawable/ic_stop_holo_dark" />
<ImageButton
- android:id="@+id/bookmark"
+ android:id="@+id/forward"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- style="@style/HoloButton"
- android:src="@drawable/btn_imageview_star"
- />
+ android:src="@drawable/ic_forward_holo_dark"
+ style="@style/HoloButton" />
</LinearLayout>
-
- <com.android.browser.PageProgressView
- android:id="@+id/progress_horizontal"
+ <LinearLayout
+ android:id="@+id/autologin"
+ android:background="#FBF0A0"
+ android:gravity="center_vertical"
+ android:paddingTop="3dip"
+ android:visibility="gone"
+ android:layout_below="@+id/taburlbar"
android:layout_width="match_parent"
- android:layout_height="22dip"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip">
+ <TextView
+ android:text="@string/autologin_bar_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@android:color/primary_text_light"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ <Spinner
+ android:id="@+id/autologin_account"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="24dp"
+ style="@android:style/Widget.Holo.Light.Spinner" />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip">
+ <Button
+ android:id="@+id/autologin_close"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:text="@string/autologin_bar_hide_text"
+ style="@android:style/Widget.Holo.Light.Button" />
+ <ProgressBar
+ android:id="@+id/autologin_progress"
+ android:indeterminateOnly="true"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:visibility="invisible" />
+ <Button
+ android:id="@+id/autologin_login"
+ android:text="@string/autologin_bar_login_text"
+ style="@android:style/Widget.Holo.Light.Button"
+ android:layout_height="wrap_content"
+ android:layout_width="0dip"
+ android:layout_weight="1" />
+ </LinearLayout>
+ <TextView
+ android:id="@+id/autologin_error"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textColor="#dd6826"
+ android:text="@string/autologin_bar_error"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:visibility="gone" />
+ </LinearLayout>
+ <com.android.browser.PageProgressView
+ android:id="@+id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:background="@null"
+ android:layout_below="@+id/taburlbar"
android:src="@drawable/progress"
- android:layout_marginTop="-11dip"
+ android:layout_marginTop="-8dip"
android:visibility="gone" />
-</LinearLayout>
+</RelativeLayout>
diff --git a/res/layout/url_bar.xml b/res/layout/url_bar.xml
index 43bbdcd..3864b7d 100644
--- a/res/layout/url_bar.xml
+++ b/res/layout/url_bar.xml
@@ -76,32 +76,26 @@
android:layout_height="48dip"
android:orientation="horizontal"
android:background="@drawable/bg_urlbar">
- <LinearLayout
- android:id="@+id/navbuttons"
+ <ImageButton
+ android:id="@+id/back"
+ android:src="@drawable/ic_back_holo_dark"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:orientation="horizontal">
- <ImageButton
- android:id="@+id/back"
- android:src="@drawable/ic_back_holo_dark"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="16dip"
- style="@style/HoloButton" />
- <ImageButton
- android:id="@+id/forward"
- android:src="@drawable/ic_forward_holo_dark"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- style="@style/HoloButton" />
- <ImageButton
- android:id="@+id/stop"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- style="@style/HoloButton"
- android:gravity="center_vertical"
- android:src="@drawable/ic_stop_holo_dark" />
- </LinearLayout>
+ android:paddingLeft="16dip"
+ style="@style/HoloButton" />
+ <ImageButton
+ android:id="@+id/forward"
+ android:src="@drawable/ic_forward_holo_dark"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@style/HoloButton" />
+ <ImageButton
+ android:id="@+id/stop"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@style/HoloButton"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_stop_holo_dark" />
<LinearLayout
android:id="@+id/urlbar_focused"
android:layout_width="0dip"
@@ -124,7 +118,7 @@
style="@style/HoloIcon"
android:visibility="gone" />
<com.android.browser.UrlInputView
- android:id="@+id/url_focused"
+ android:id="@+id/url"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="match_parent"
diff --git a/res/layout/tab_view_add_tab.xml b/res/layout/webview_preview.xml
similarity index 62%
copy from res/layout/tab_view_add_tab.xml
copy to res/layout/webview_preview.xml
index f4e0f02..6edbcce 100644
--- a/res/layout/tab_view_add_tab.xml
+++ b/res/layout/webview_preview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2011 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.
@@ -15,25 +15,24 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_width="match_parent"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- >
- <ImageView
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:src="@drawable/ic_new_window_holo_dark"/>
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingRight="6dip"
+ android:paddingTop="6dip"
+ android:paddingBottom="6dip"
+ android:paddingLeft="8dip">
+
<TextView
- android:layout_width="match_parent"
+ android:text="@string/preview"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end"
- android:text="@string/new_tab"
- />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <WebView
+ android:id="@+id/webview"
+ android:layout_width="match_parent"
+ android:layout_height="180dp" />
+
</LinearLayout>
+
diff --git a/res/layout/widget_account_selection.xml b/res/layout/widget_account_selection.xml
new file mode 100644
index 0000000..5dcd210
--- /dev/null
+++ b/res/layout/widget_account_selection.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:fadingEdgeLength="16dip" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="beginning"
+ android:dividerPadding="16dip"
+ android:background="@null">
+ <LinearLayout
+ style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingLeft="2dip"
+ android:paddingRight="2dip"
+ android:measureWithLargestChild="true"
+ android:background="@null">
+ <Button
+ android:id="@+id/cancel"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
+
diff --git a/res/menu-sw600dp/browser.xml b/res/menu-sw600dp/browser.xml
index be4a521..23366e7 100644
--- a/res/menu-sw600dp/browser.xml
+++ b/res/menu-sw600dp/browser.xml
@@ -34,6 +34,9 @@
android:alphabeticShortcut="s" />
<item android:id="@+id/save_webarchive_menu_id"
android:title="@string/menu_save_webarchive" />
+ <item
+ android:id="@+id/freeze_tab_menu_id"
+ android:title="@string/menu_freeze_tab" />
<item android:id="@+id/page_info_menu_id"
android:title="@string/page_info"
android:icon="@drawable/ic_pageinfo_holo_dark"
diff --git a/res/menu/bookmark.xml b/res/menu/bookmark.xml
index 3305c70..3d248b4 100644
--- a/res/menu/bookmark.xml
+++ b/res/menu/bookmark.xml
@@ -26,12 +26,15 @@
android:showAsAction="always" />
<item
android:id="@+id/thumbnail_view"
- android:title="@string/bookmark_thumbnail_view"/>
+ android:title="@string/bookmark_thumbnail_view"
+ android:icon="@drawable/ic_thumbnail_view_holo_dark" />
<item
android:id="@+id/list_view"
- android:title="@string/bookmark_list_view"/>
+ android:title="@string/bookmark_list_view"
+ android:icon="@drawable/ic_list_view_holo_dark" />
<item
android:id="@+id/preferences_menu_id"
android:title="@string/menu_preferences"
+ android:icon="@drawable/ic_settings_holo_dark"
android:alphabeticShortcut="p" />
</menu>
diff --git a/res/menu/browser.xml b/res/menu/browser.xml
index abe3716..6eadcba 100644
--- a/res/menu/browser.xml
+++ b/res/menu/browser.xml
@@ -15,55 +15,80 @@
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <group android:id="@+id/MAIN_MENU">
- <item android:id="@+id/new_tab_menu_id"
- android:title="@string/new_tab"
- android:icon="@drawable/ic_menu_new_window"
- android:alphabeticShortcut="n" />
- <item android:id="@+id/bookmarks_menu_id"
- android:title="@string/bookmarks"
- android:alphabeticShortcut="b"
- android:icon="@drawable/ic_bookmarks_holo_dark" />
- <item android:id="@+id/active_tabs_menu_id"
- android:title="@string/active_tabs"
- android:icon="@drawable/ic_windows_holo_dark"
- android:alphabeticShortcut="t" />
- <item android:id="@+id/stop_reload_menu_id"
- android:alphabeticShortcut="r" />
- <item android:id="@+id/forward_menu_id"
- android:title="@string/forward"
- android:icon="@*android:drawable/ic_menu_forward" />
- <item android:id="@+id/add_bookmark_menu_id"
+ <group
+ android:id="@+id/MAIN_MENU">
+ <group
+ android:id="@+id/NAV_MENU">
+ <item
+ android:id="@+id/new_tab_menu_id"
+ android:title="@string/new_tab"
+ android:icon="@drawable/ic_menu_new_window"
+ android:alphabeticShortcut="n" />
+ <item
+ android:id="@+id/bookmarks_menu_id"
+ android:title="@string/bookmarks"
+ android:alphabeticShortcut="b"
+ android:icon="@drawable/ic_bookmarks_holo_dark" />
+ <item
+ android:id="@+id/active_tabs_menu_id"
+ android:title="@string/active_tabs"
+ android:icon="@drawable/ic_windows_holo_dark"
+ android:alphabeticShortcut="t" />
+ <item
+ android:id="@+id/stop_reload_menu_id"
+ android:alphabeticShortcut="r" />
+ <item
+ android:id="@+id/forward_menu_id"
+ android:title="@string/forward"
+ android:icon="@*android:drawable/ic_menu_forward" />
+ </group>
+ <item
+ android:id="@+id/incognito_menu_id"
+ android:title="@string/incognito_tab"
+ android:icon="@drawable/ic_new_incognito_holo_dark" />
+ <item
+ android:id="@+id/add_bookmark_menu_id"
android:title="@string/save_to_bookmarks"
android:icon="@drawable/ic_bookmark_on_holo_dark"
android:alphabeticShortcut="d" />
- <item android:id="@+id/find_menu_id"
+ <item
+ android:id="@+id/find_menu_id"
android:title="@*android:string/find_on_page"
android:icon="@*android:drawable/ic_menu_find"
android:alphabeticShortcut="f" />
- <item android:id="@+id/share_page_menu_id"
+ <item
+ android:id="@+id/share_page_menu_id"
android:title="@string/share_page"
android:icon="@drawable/ic_share_holo_dark"
android:alphabeticShortcut="s" />
- <item android:id="@+id/save_webarchive_menu_id"
+ <item
+ android:id="@+id/save_webarchive_menu_id"
android:title="@string/menu_save_webarchive" />
- <item android:id="@+id/page_info_menu_id"
+ <item
+ android:id="@+id/freeze_tab_menu_id"
+ android:title="@string/menu_freeze_tab" />
+ <item
+ android:id="@+id/page_info_menu_id"
android:title="@string/page_info"
android:icon="@drawable/ic_pageinfo_holo_dark"
android:alphabeticShortcut="g" />
- <item android:id="@+id/view_downloads_menu_id"
+ <item
+ android:id="@+id/view_downloads_menu_id"
android:title="@string/menu_view_download"
android:icon="@drawable/ic_downloads_holo_dark"
android:alphabeticShortcut="j" />
- <item android:id="@+id/preferences_menu_id"
+ <item
+ android:id="@+id/preferences_menu_id"
android:title="@string/menu_preferences"
android:icon="@drawable/ic_settings_holo_dark"
android:alphabeticShortcut="p" />
<!-- followings are debug only -->
- <item android:id="@+id/dump_nav_menu_id"
+ <item
+ android:id="@+id/dump_nav_menu_id"
android:title="@string/dump_nav"
android:visible="false" />
- <item android:id="@+id/dump_counters_menu_id"
+ <item
+ android:id="@+id/dump_counters_menu_id"
android:title="@string/dump_counters"
android:visible="false" />
</group>
diff --git a/res/raw/most_visited.ktpl b/res/raw/most_visited.ktpl
index 04b9eee..9a6e1b8 100644
--- a/res/raw/most_visited.ktpl
+++ b/res/raw/most_visited.ktpl
@@ -3,7 +3,7 @@
<html>
<head>
<title><%@ string/new_tab %></title>
-<meta name="viewport" content="width=device-width; initial-scale=1.0;" />
+<meta name="viewport" content="width=device-width; initial-scale=1.0; user-scalable=0" />
<style type="text/css">
@@ -14,20 +14,19 @@
body {
text-align: center;
- margin: 16px auto;
+ margin: 0px auto;
padding: 0 8px 0 8px;
max-width: <%@ dimen/mv_max_width %>px;
}
-#most_visited h3 {
+h3 {
text-align: center;
- padding: 0;
- margin: 5px 0 5px 0px;
+ margin: 5px 0 5px 0;
}
.thumbwrap li {
display: inline-block;
- margin: 0 7px 15px 7px;
+ margin: 0 7px 12px 7px;
padding: 0;
}
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
new file mode 100644
index 0000000..03713f1
--- /dev/null
+++ b/res/values-am/strings.xml
@@ -0,0 +1,622 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 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" msgid="1935869255545976415">"አሳሽ"</string>
+ <string name="choose_upload" msgid="3649366287575002063">"ለመስቀል ፋይል ምረጥ"</string>
+ <!-- no translation found for uploads_disabled (463761197575372994) -->
+ <skip />
+ <string name="new_tab" msgid="4505722538297295141">"አዲሰ መስኮት"</string>
+ <string name="new_incognito_tab" msgid="5821404839654751753">"አዲስ incognito መስኮት"</string>
+ <string name="active_tabs" msgid="3050623868203544623">"ዊንዶውስ"</string>
+ <string name="tab_bookmarks" msgid="2305793036003473653">"ዕልባቶች"</string>
+ <string name="tab_most_visited" msgid="1077402532455000703">"በብዛት የተጎበኘ"</string>
+ <string name="tab_history" msgid="1979267558744613746">"ታሪክ"</string>
+ <string name="added_to_bookmarks" msgid="1020224130695956728">"ወደ እልባቶች ታክሏል"</string>
+ <string name="removed_from_bookmarks" msgid="6063705902028438800">"ከዕልባት የተወገደ"</string>
+ <string name="sign_in_to" msgid="5939425800148759165">"ወደ <xliff:g id="HOSTNAME">%s1</xliff:g>\"<xliff:g id="REALM">%s2</xliff:g>\" ግባ"</string>
+ <!-- no translation found for username (5057566336518215922) -->
+ <skip />
+ <!-- no translation found for password (1177138552305184404) -->
+ <skip />
+ <!-- no translation found for action (183105774472071343) -->
+ <skip />
+ <string name="bookmarks_search" msgid="5229596268214362873">"አሳሽ"</string>
+ <!-- no translation found for cancel (3017274947407233702) -->
+ <skip />
+ <!-- no translation found for ok (1509280796718850364) -->
+ <skip />
+ <string name="title_bar_loading" msgid="7438217780834640678">"በማስገባት ላይ..."</string>
+ <!-- no translation found for page_info (4048529256302257195) -->
+ <skip />
+ <!-- no translation found for page_info_view (5303490449842635158) -->
+ <skip />
+ <!-- no translation found for page_info_address (2222306609532903254) -->
+ <skip />
+ <!-- no translation found for ssl_warnings_header (79744901983636370) -->
+ <skip />
+ <!-- no translation found for ssl_continue (8031515015829358457) -->
+ <skip />
+ <!-- no translation found for security_warning (6607795404322797541) -->
+ <skip />
+ <!-- no translation found for view_certificate (1472768887529093862) -->
+ <skip />
+ <!-- no translation found for ssl_go_back (4598951822061593819) -->
+ <skip />
+ <!-- no translation found for ssl_untrusted (5369967226521102194) -->
+ <skip />
+ <!-- no translation found for ssl_mismatch (558688832420069896) -->
+ <skip />
+ <!-- no translation found for ssl_expired (5739349389499575559) -->
+ <skip />
+ <!-- no translation found for ssl_not_yet_valid (2893167846212645846) -->
+ <skip />
+ <!-- no translation found for ssl_certificate (5226747157992111668) -->
+ <skip />
+ <!-- no translation found for ssl_certificate_is_valid (7096160815933145579) -->
+ <skip />
+ <!-- no translation found for issued_to (9032338008819841339) -->
+ <skip />
+ <!-- no translation found for common_name (5745530093500062357) -->
+ <skip />
+ <!-- no translation found for org_name (8868889052889991293) -->
+ <skip />
+ <!-- no translation found for org_unit (4489056376307768196) -->
+ <skip />
+ <!-- no translation found for issued_by (6959484326943152487) -->
+ <skip />
+ <!-- no translation found for validity_period (57988851973181309) -->
+ <skip />
+ <!-- no translation found for issued_on (2082890654801808368) -->
+ <skip />
+ <!-- no translation found for expires_on (8061200430557020704) -->
+ <skip />
+ <!-- no translation found for stopping (4839698519340302982) -->
+ <skip />
+ <!-- no translation found for stop (5687251076030630074) -->
+ <skip />
+ <!-- no translation found for reload (8585220783228408062) -->
+ <skip />
+ <!-- no translation found for back (8414603107175713668) -->
+ <skip />
+ <!-- no translation found for forward (4288210890526641577) -->
+ <skip />
+ <!-- no translation found for save (5922311934992468496) -->
+ <skip />
+ <!-- no translation found for do_not_save (6777633870113477714) -->
+ <skip />
+ <string name="location" msgid="3411848697912600125">"አድራሻ"</string>
+ <!-- no translation found for account (5179824606448077042) -->
+ <skip />
+ <string name="containing_folder" msgid="6771180232953030479">"ያክሉ ለ..."</string>
+ <string name="new_folder" msgid="7743540149088867917">"አዲስ አቃፊ"</string>
+ <!-- no translation found for edit_folder (621817453133656156) -->
+ <skip />
+ <!-- no translation found for delete_folder (2046483129024501116) -->
+ <skip />
+ <!-- no translation found for no_subfolders (5880411440592452802) -->
+ <skip />
+ <!-- no translation found for add_to_bookmarks_menu_option (4449323955122214389) -->
+ <skip />
+ <!-- no translation found for add_to_homescreen_menu_option (1461447829242963790) -->
+ <skip />
+ <!-- no translation found for add_to_other_folder_menu_option (5450890093372998187) -->
+ <skip />
+ <string name="name" msgid="5462672162695365387">"መሰየሚያ"</string>
+ <!-- no translation found for http (2163722670597250102) -->
+ <skip />
+ <string name="save_to_bookmarks" msgid="6101482434920313244">"ወደ እልባዎች አክል"</string>
+ <string name="bookmark_this_page" msgid="7530739804320811054">"ይህን ገፅ አልብ"</string>
+ <string name="remove" msgid="7820112494467011374">"አስወግድ"</string>
+ <!-- no translation found for edit_bookmark (5024089053490231905) -->
+ <skip />
+ <string name="create_shortcut_bookmark" msgid="1995095662095484289">"አቋራጭን ወደ መነሻ አክል"</string>
+ <!-- no translation found for open_bookmark (8473581305759935790) -->
+ <skip />
+ <!-- no translation found for remove_bookmark (8407495852801410891) -->
+ <skip />
+ <string name="remove_from_bookmarks" msgid="4374080666576982775">"ከዕልባቶች አስወግድ"</string>
+ <!-- no translation found for remove_history_item (5021424935726728618) -->
+ <skip />
+ <string name="set_as_homepage" msgid="4752937379414905560">"እንደ መነሻገፅ አዘጋጅ"</string>
+ <!-- no translation found for bookmark_saved (2766434679871317557) -->
+ <skip />
+ <string name="bookmark_not_saved" msgid="700600955089376724">"ዕልባትለማስቀመጥ አልተቻለም።"</string>
+ <string name="homepage_set" msgid="8768087280310966395">"መነሻ ገፅ አዘጋጅ።"</string>
+ <string name="bookmark_needs_title" msgid="6245900436119218187">"ዕልባቶች መጠሪያ አላቸው።"</string>
+ <string name="bookmark_needs_url" msgid="7809876865972755158">"ዕልባቶች መጠሪያ አላቸው።"</string>
+ <!-- no translation found for bookmark_url_not_valid (6719785633980202419) -->
+ <skip />
+ <string name="bookmark_cannot_save_url" msgid="791722768778386941">"ይህ URL እልባት ሊደረግበት አልቻለም።"</string>
+ <!-- no translation found for delete_bookmark (2422989994934201992) -->
+ <skip />
+ <!-- no translation found for bookmark_page (6845189305130307274) -->
+ <skip />
+ <!-- no translation found for bookmark_thumbnail_view (3164068314718522138) -->
+ <skip />
+ <!-- no translation found for bookmark_list_view (7848510619500937839) -->
+ <skip />
+ <string name="current_page" msgid="7510129573681663135">"ከ "</string>
+ <string name="delete_bookmark_warning" msgid="758043186202032205">"\"<xliff:g id="BOOKMARK">%s</xliff:g>\" ዕልባት ይሰረዛል።"</string>
+ <!-- no translation found for open_all_in_new_window (6514602245828366045) -->
+ <skip />
+ <string name="goto_dot" msgid="3895839050522602723">"ሂድ"</string>
+ <string name="incognito_tab" msgid="5419458065370134289">"አዲስ incognito ትር ክፈት"</string>
+ <string name="select_dot" msgid="6299170761900561967">"ፅሁፍ ምረጥ"</string>
+ <!-- no translation found for tab_picker_title (864478399057782913) -->
+ <skip />
+ <!-- no translation found for tab_picker_remove_tab (630087809802479397) -->
+ <skip />
+ <!-- no translation found for bookmarks (1961279134885867815) -->
+ <skip />
+ <!-- no translation found for shortcut_bookmark (3974876480401135895) -->
+ <skip />
+ <!-- no translation found for history (2451240511251410032) -->
+ <skip />
+ <!-- no translation found for menu_view_download (2124570321712995120) -->
+ <skip />
+ <string name="copy_page_url" msgid="7635062169011319208">"url ገፅ ቅዳ"</string>
+ <!-- no translation found for share_page (593756995297268343) -->
+ <skip />
+ <!-- outdated translation 3934652434001459581 --> <string name="menu_save_webarchive" msgid="2474117375302625691">"እንደ ድረ መዝገብ አስቀምጥ"</string>
+ <!-- outdated translation 7045250341467345007 --> <string name="webarchive_saved" msgid="2212053339474523406">"የድረ መዝገብ ተቀምጧል።"</string>
+ <!-- outdated translation 2880998204746620260 --> <string name="webarchive_failed" msgid="19950914584285713">"የድረ መዝገብ ለማስቀመጥ ተሳነ"</string>
+ <!-- no translation found for contextheader_folder_bookmarkcount (353987136645619089) -->
+ <skip />
+ <!-- no translation found for contextheader_folder_empty (974171637803391651) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink (7237961252214188935) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow (992765050093960353) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow_background (5556131402560251639) -->
+ <skip />
+ <!-- no translation found for contextmenu_savelink (5508554930832538184) -->
+ <skip />
+ <!-- no translation found for contextmenu_sharelink (5392275392280130331) -->
+ <skip />
+ <!-- no translation found for contextmenu_copy (398860586635404030) -->
+ <skip />
+ <!-- no translation found for contextmenu_copylink (5153657160294534270) -->
+ <skip />
+ <!-- no translation found for contextmenu_download_image (4243829645180686912) -->
+ <skip />
+ <!-- no translation found for contextmenu_view_image (3870625602053600905) -->
+ <skip />
+ <string name="contextmenu_set_wallpaper" msgid="3691902960115350686">"እንደ ልጥፍ አዘጋጅ"</string>
+ <!-- no translation found for contextmenu_dial_dot (5856550683415933806) -->
+ <skip />
+ <!-- no translation found for contextmenu_add_contact (3183511922223645716) -->
+ <skip />
+ <!-- no translation found for contextmenu_send_mail (1014513374828775660) -->
+ <skip />
+ <!-- no translation found for contextmenu_map (7471390435434034912) -->
+ <skip />
+ <string name="choosertitle_sharevia" msgid="4600490613341909086">"በ በኩል አጋራ"</string>
+ <!-- no translation found for clear (7070043081700011461) -->
+ <skip />
+ <!-- no translation found for replace (4843033491070384047) -->
+ <skip />
+ <!-- no translation found for browser_bookmarks_page_bookmarks_text (6787605028726162673) -->
+ <skip />
+ <!-- no translation found for menu_preferences (6709237687234102240) -->
+ <skip />
+ <!-- no translation found for pref_content_title (722227111894838633) -->
+ <skip />
+ <!-- no translation found for pref_content_load_images (2125616852957377561) -->
+ <skip />
+ <string name="pref_content_load_images_summary" msgid="5055874125248398584">"በድህረ ገፆች ላይ ምስሎች አሳይ"</string>
+ <!-- no translation found for pref_content_block_popups (4158524847764470895) -->
+ <skip />
+ <!-- no translation found for pref_content_javascript (4570972030299516843) -->
+ <skip />
+ <!-- no translation found for pref_content_open_in_background (824123779725118663) -->
+ <skip />
+ <string name="pref_content_plugins" msgid="7231944644794301582">"ተሰኪዎችን አስችል"</string>
+ <string-array name="pref_content_plugins_choices">
+ <item msgid="6745108155096660725">"ሁልጊዜ እንደበራ"</item>
+ <item msgid="2484126708670016519">"በጥየቃ ላይ"</item>
+ <item msgid="8547442717307793863">"ውጪ"</item>
+ </string-array>
+ <string name="pref_content_open_in_background_summary" msgid="1737664075721181678">"ክፈት"</string>
+ <!-- no translation found for pref_content_homepage (3324574611613105696) -->
+ <skip />
+ <string name="pref_content_search_engine" msgid="1620101310821644144">"የፍለጋ ፍርግም አዘጋጅ"</string>
+ <string name="pref_content_search_engine_summary" msgid="5162667665858487316">"የፍለጋ ፍርግም ምረጥ"</string>
+ <!-- no translation found for pref_set_homepage_to (7196350233061395098) -->
+ <skip />
+ <!-- outdated translation 1493179933653044553 --> <string name="pref_use_current" msgid="1778622474040406672">"የአሁኑን ገፅ ተጠቀም"</string>
+ <!-- no translation found for pref_use_blank (8503238592551111169) -->
+ <skip />
+ <!-- no translation found for pref_use_default (192587563274735878) -->
+ <skip />
+ <!-- no translation found for pref_content_autofit (8260474534053660809) -->
+ <skip />
+ <string name="pref_content_autofit_summary" msgid="4587831659894879986">"ማያውን ለማስማማት ድረ ገፆችን ቅረፅ"</string>
+ <!-- no translation found for pref_general_title (1946872771219249323) -->
+ <skip />
+ <!-- no translation found for pref_general_sync_title (3138637035975860324) -->
+ <skip />
+ <!-- no translation found for pref_general_autofill_title (547881256865816858) -->
+ <skip />
+ <string name="pref_personal_sync_with_chrome" msgid="1695182180332194033">"Google Chrome አሳምር"</string>
+ <string name="pref_personal_sync_with_chrome_summary" msgid="7414133931827321055">"እልባቶች & ሌላ ውሂብ በAndroid አሳሽ እና Google Chrome መካከል አጋራ"</string>
+ <string name="pref_personal_google_account" msgid="952360133341490071">"የGoogle መለያ"</string>
+ <string name="pref_personal_sync_bookmarks" msgid="59237515966184432">"እልባቶችን አሳምር"</string>
+ <string name="pref_personal_sync_bookmarks_summary" msgid="4791767605662205482">"እልባቶችን ከGoogle Chrome እና Android ማሰሻ ጋር አሳምር"</string>
+ <string name="pref_personal_start_syncing" msgid="6046972042512655232">"አሳምር ጀምር"</string>
+ <string name="pref_personal_account_dialog_title" msgid="1390867119887955530">"ለማጋራት የGoogle መለያ ምረጥ"</string>
+ <!-- outdated translation 1174197447388234595 --> <string name="pref_autofill_enabled" msgid="1015751713312396713">"የራስ ሙላ ቅፅ"</string>
+ <string name="pref_autofill_enabled_summary" msgid="422640696197018914">"በነጠላ ጠቅታ የድረ ቅፆችን ሙላ"</string>
+ <!-- outdated translation 1350709161524642663 --> <string name="pref_autofill_profile_editor" msgid="3864116896052437796">"የራስሙላ ቅንብሮች"</string>
+ <!-- unknown quoting pattern: original -1, translation 1 -->
+ <!-- outdated translation 6748434431641768870 --> <string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"ጫን &amp; ለራስሙላ ቅፆች ውሂብ አደራጅ"</string>
+ <!-- no translation found for pref_autologin_title (2362827272595366379) -->
+ <skip />
+ <!-- no translation found for pref_autologin_progress (8333244467048833461) -->
+ <skip />
+ <!-- no translation found for autologin_bar_text (3684581827167173371) -->
+ <skip />
+ <!-- no translation found for autologin_bar_login_text (7052816600314556734) -->
+ <skip />
+ <!-- no translation found for autologin_bar_hide_text (3629355974385859580) -->
+ <skip />
+ <!-- no translation found for autologin_bar_error (5132514366023044839) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_heading (8392952553626722083) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_name (8566130291459685955) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_email_address (7967585896612797173) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_company_name (2813443159949210417) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1 (836433242509243081) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1_hint (5965659598509327172) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2 (8194745202893822479) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2_hint (2048330295853546405) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_city (4193225955409148508) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_state (8549739922338171458) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_zip_code (283668573295656671) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_country (7234470301239156656) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number (4938852821413729276) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number_invalid (7166394872369167580) -->
+ <skip />
+ <string name="autofill_profile_editor_save_profile" msgid="8349915287435262888">"መገለጫ አስቀምጥ"</string>
+ <!-- no translation found for autofill_profile_successful_save (6834102203944938409) -->
+ <skip />
+ <!-- no translation found for autofill_profile_successful_delete (2421442112954362732) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_delete_profile (2754563301088418752) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_message (6605682320156223114) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_negative_toast (6990737008936188620) -->
+ <skip />
+ <!-- no translation found for disable_autofill (8305901059849400354) -->
+ <skip />
+ <!-- no translation found for pref_privacy_security_title (3480313968942160914) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cache (3380316479925886998) -->
+ <skip />
+ <string name="pref_privacy_clear_cache_summary" msgid="2216463577207991454">"በአካባቢ የተሸጎጠ ይዘት እና የውሂብ ጎታዎችን አጥራ"</string>
+ <string name="pref_privacy_clear_cache_dlg" msgid="5541011591300753881">"እዛው አካባቢየተሸጎጠ ይዘት እና የውሂብ ጎታዎች ይሰረዛሉ።"</string>
+ <!-- no translation found for pref_privacy_cookies_title (6763274282214830526) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cookies (3095583579133780331) -->
+ <skip />
+ <string name="pref_privacy_clear_cookies_summary" msgid="6962742063990677520">"ሁሉንም የአሳሽ ኩኪዎች አጥራ"</string>
+ <string name="pref_privacy_clear_cookies_dlg" msgid="552855688091432682">"ሁሉምኩኪዎች ይሰረዛሉ።"</string>
+ <!-- no translation found for pref_privacy_clear_history (8723795508825198477) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_history_summary (6868501330708940734) -->
+ <skip />
+ <string name="pref_privacy_clear_history_dlg" msgid="544903007914753853">"የአሳሹ መዳሰሻ ታሪክ ይሰረዛል።"</string>
+ <!-- no translation found for pref_privacy_formdata_title (6549813837982050424) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data (4232668196344383987) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data_summary (1790390894719517167) -->
+ <skip />
+ <string name="pref_privacy_clear_form_data_dlg" msgid="4443621086781197928">"የተቀመጡ የውሂብ ቅፆች ሁሉ ይሰረዛሉ።"</string>
+ <!-- no translation found for pref_privacy_clear_passwords (4750234112289277480) -->
+ <skip />
+ <string name="pref_privacy_clear_passwords_summary" msgid="8856782718942903335">"የተቀመጡ ይለፍ ቃሎችን ሁሉ አጥራ"</string>
+ <string name="pref_privacy_clear_passwords_dlg" msgid="2083869328824248255">"የተቀመጡ የይለፍ ቃሎች ሁሉ ይሰረዛሉ።"</string>
+ <!-- no translation found for pref_privacy_location_title (7458378016606081067) -->
+ <skip />
+ <string name="pref_privacy_enable_geolocation" msgid="1395040170290765686">"ሥፍራ አስችል"</string>
+ <string name="pref_privacy_enable_geolocation_summary" msgid="8437020934664306205">"ድረ ገፆች ወደ እርስዎ ሥፍራ ድረስ ለመጠየቅ ፍቀድ"</string>
+ <string name="pref_privacy_clear_geolocation_access" msgid="6649680770030042980">"የስፍራ መድረሻ አፅዳ"</string>
+ <string name="pref_privacy_clear_geolocation_access_summary" msgid="7750143359497314679">"ለሁሉም ድረ ገፆች የስፍራ ድረስ አጥራ"</string>
+ <string name="pref_privacy_clear_geolocation_access_dlg" msgid="7327063124488827244">"ለሁሉም ድረ ገፆች የስፍራ ድረስ አጥራ"</string>
+ <!-- no translation found for pref_security_passwords_title (5734190542383756711) -->
+ <skip />
+ <!-- no translation found for pref_security_remember_passwords (6492957683454529549) -->
+ <skip />
+ <string name="pref_security_remember_passwords_summary" msgid="256388703356349137">"ለድረ ገፆች ተጠቃሚ ስሞች እና የይለፍ ቃሎች አስቀምጥ"</string>
+ <!-- no translation found for pref_security_save_form_data (1213669802810198893) -->
+ <skip />
+ <!-- no translation found for pref_security_save_form_data_summary (4994074685153708026) -->
+ <skip />
+ <!-- no translation found for pref_security_show_security_warning (8901135676266754559) -->
+ <skip />
+ <string name="pref_security_show_security_warning_summary" msgid="8968906112720511704">"ከድረ ገፅ ደህንነት ጋር ችግር ካለማስጠንቀቂያ አሳይ"</string>
+ <!-- no translation found for pref_security_accept_cookies (3201367661925047989) -->
+ <skip />
+ <string name="pref_security_accept_cookies_summary" msgid="1465118934875026920">"ድረ ገፆች እንዲያስቀምጡ እና \"ኩኪ\" ውሂብ እንዲያነቡ ፍቀድ"</string>
+ <!-- no translation found for pref_text_size (3827031324346612208) -->
+ <skip />
+ <string-array name="pref_text_size_choices">
+ <item msgid="4952686548944739548">"ደቃቃ"</item>
+ <item msgid="1950030433642671460">"አነስተኛ"</item>
+ <item msgid="4338347520133294584">"መደበኛ"</item>
+ <item msgid="5043128215356351184">"ትልቅ"</item>
+ <item msgid="7201512237890458902">"ግዙፍ"</item>
+ </string-array>
+ <!-- no translation found for pref_text_size_dialogtitle (3625388833512647865) -->
+ <skip />
+ <!-- no translation found for pref_min_font_size (8811125835817449131) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable (5641500562399892621) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable_summary (4431962409438162448) -->
+ <skip />
+ <string name="pref_default_zoom" msgid="8076142259097187395">"ነባሪ አጉላ"</string>
+ <string-array name="pref_default_zoom_choices">
+ <item msgid="549583171195154919">"ሩቅ"</item>
+ <item msgid="5619034257768161024">"መካከለኛ"</item>
+ <item msgid="3840999588443167001">"ዝጋ"</item>
+ </string-array>
+ <string name="pref_default_zoom_dialogtitle" msgid="6095974367125109021">"ነባሪ አጉላ"</string>
+ <string name="pref_content_load_page" msgid="2219810141690955452">"ክፈት"</string>
+ <string name="pref_content_load_page_summary" msgid="8792093504054149369">"አዲስ የተከፈቱ ገፆችን በጠቅላይ ቅኝት አሳይ"</string>
+ <!-- no translation found for pref_extras_title (7075456173747370647) -->
+ <skip />
+ <string name="pref_extras_website_settings" msgid="67866640052455549">"የድረ ገፅ ቅንብሮች"</string>
+ <string name="pref_extras_website_settings_summary" msgid="1656771443223494406">"ለነጠላ ድረ ገጾች የላቁ ቅንብሮች"</string>
+ <!-- no translation found for pref_extras_reset_default_title (3579760449455761762) -->
+ <skip />
+ <!-- no translation found for pref_extras_reset_default (8904000515846202110) -->
+ <skip />
+ <string name="pref_extras_reset_default_summary" msgid="4247870778270414501">"ነባሪ ቅንብሮችን እነበረበት መልስ"</string>
+ <string name="pref_extras_reset_default_dlg" msgid="6640261575874704022">"ቅንብሮች ወደ ነባሪ ዋጋቸው ያድህራሉ።"</string>
+ <!-- no translation found for pref_extras_reset_default_dlg_title (2250334970728938936) -->
+ <skip />
+ <!-- no translation found for pref_development_title (3263854204533056480) -->
+ <skip />
+ <string name="pref_default_text_encoding" msgid="5742965543955558478">"ፅሁፍ በኮድ መክተት"</string>
+ <string-array name="pref_default_text_encoding_choices">
+ <item msgid="7275223955790513818">"-1 (-1"</item>
+ <item msgid="2456597866837587140">"ዩኒኮድ(UTF-8)"</item>
+ <item msgid="6122474363777211732">"ቻይንኛ (GBK)"</item>
+ <item msgid="373372275931607040">"ቻይንኛ (Big5)"</item>
+ <item msgid="891615911084608570">"ጃፓንኛ (ISO-2022-JP)"</item>
+ <item msgid="5589150448475151241">"ጃፓንኛ (SHIFT_JIS)"</item>
+ <item msgid="7356792686950371843">"ጃፓንኛ (EUC-JP)"</item>
+ <item msgid="2193955365569270096">"ኮሪያኛ (EUC-KR)"</item>
+ </string-array>
+ <string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"ፅሁፍ በኮድ መክተት"</string>
+ <!-- no translation found for pref_accessibility_title (5127836981587423215) -->
+ <skip />
+ <!-- no translation found for pref_lab_title (5571091610359629423) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls (3267606522082281367) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls_summary (1564546156544675707) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage (7597766876952506909) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage_summary (4132511544800457513) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search (1119176077760723740) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search_summary (839320474961917522) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen (8173609016657987973) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen_summary (6853711692160711419) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher (9063310468293037499) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher_summary (1782363693543953474) -->
+ <skip />
+ <!-- no translation found for help_useragent_switcher (123586256526014375) -->
+ <skip />
+ <!-- no translation found for browserFrameNetworkErrorLabel (126892350904924893) -->
+ <skip />
+ <!-- no translation found for browserFrameFileErrorLabel (8063691502792670367) -->
+ <skip />
+ <!-- no translation found for browserFrameFormResubmitLabel (2685923472682180360) -->
+ <skip />
+ <string name="browserFrameFormResubmitMessage" msgid="2752182215695632138">"ለማየት እየሞከሩ ያሉት ገፅ (\"POSTDATA\") ተብሎ የተረከበ ውሂብ ይዝዋል። ውሂቡን ድጋሚ ከላኩት፣ ማንኛውም በገፁ ቅፅላይ ያለ ርምጃ ይከናወናል(ለምሳሌ ፍለጋ ወይም የመስመር ላይ ግዢ) ይደገማል።"</string>
+ <!-- no translation found for loadSuspendedTitle (675991625288706944) -->
+ <skip />
+ <string name="loadSuspended" msgid="3133656588880851273">"አሳሽ ይህን ገፅ ማስገባት አልቻለም ምክያቱም የበይነመረብ ተያያዥነት የለም።"</string>
+ <!-- no translation found for clear_history (5998307092715979619) -->
+ <skip />
+ <string name="browser_history" msgid="1038987118290272525">"በቅርብ ጊዜ የተጎበኙ ገፆች"</string>
+ <!-- no translation found for empty_history (8738772352308207274) -->
+ <skip />
+ <string name="add_new_bookmark" msgid="8086367791400349049">"እልባት አክል..."</string>
+ <string name="add_bookmark_short" msgid="3783984330998103735">"አክል"</string>
+ <string name="search_hint" msgid="4647356319916631820">"ፈልግ ወይም URL ፃፍ"</string>
+ <!-- no translation found for search_button_text (5235226933877634410) -->
+ <skip />
+ <string name="search_settings_description" msgid="1422401062529014107">"የዕልባቶች እና ድረ ታሪክ"</string>
+ <!-- no translation found for attention (3473639060042811244) -->
+ <skip />
+ <string name="popup_window_attempt" msgid="2673111696288657989">"ይህ ድረ ገፅ ብቅባይ መስኮት ለመክፈት እየሞከረ ነው።"</string>
+ <!-- no translation found for allow (1157313689171991335) -->
+ <skip />
+ <!-- no translation found for block (9172175889884707800) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_title (5175503564948906442) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_message (1398571800233959583) -->
+ <skip />
+ <!-- no translation found for too_many_subwindows_dialog_title (3805453941587725944) -->
+ <skip />
+ <string name="too_many_subwindows_dialog_message" msgid="5827289829907966657">"አዲስ ብቅባይ መስኮት መክፈት አልተቻለም ምክንያቱም በአንድ ጊዜ አንድ ብቻ ይከፈታል።"</string>
+ <!-- no translation found for download_title (2122874021047565594) -->
+ <skip />
+ <!-- no translation found for download_unknown_filename (4013465542563652175) -->
+ <skip />
+ <!-- no translation found for download_menu_open (4888327480367757513) -->
+ <skip />
+ <!-- no translation found for download_menu_clear (6264454531553418124) -->
+ <skip />
+ <string name="download_menu_delete" msgid="8815502136393894148">"ሰርዝ"</string>
+ <!-- no translation found for download_menu_cancel (2545333007601851574) -->
+ <skip />
+ <!-- no translation found for download_menu_cancel_all (2136550823151999166) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_title (8909108500262799748) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_msg (6285389170052357797) -->
+ <skip />
+ <string name="download_delete_file" msgid="5330036497843073249">"ፋይሉ ይሰረዛል"</string>
+ <!-- no translation found for download_file_error_dlg_title (2693630283595384874) -->
+ <skip />
+ <string name="download_file_error_dlg_msg" msgid="5156405410324072471">"<xliff:g id="FILENAME">%s</xliff:g> ማውረድ አልተቻለም።"\n" ስልክዎ ላይ ትንሽ ቦታ ያስለቅቁ እና እንደገና ይሞክሩ።"</string>
+ <!-- no translation found for download_failed_generic_dlg_title (6106781095337833391) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (56777245081568508) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (605904452159416792) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (3144652102051031721) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (2616399456116301518) -->
+ <skip />
+ <!-- outdated translation 6877712666046917741 --> <string name="download_sdcard_busy_dlg_title" product="nosdcard" msgid="8081445664689818973">"SD ካር ድ የለም"</string>
+ <string name="download_sdcard_busy_dlg_title" product="default" msgid="6877712666046917741">"SD ካር ድ የለም"</string>
+ <!-- outdated translation 3473883538192835204 --> <string name="download_sdcard_busy_dlg_msg" product="nosdcard" msgid="3979329954835690147">"የ SD ካርዱ ስራ ላይነው። ማውረድ ለመፍቀድ፣ በማሳወቂያ ውስጥ \"የUSB ማከማቻ አጥፋ\" ንምረጥ።"</string>
+ <string name="download_sdcard_busy_dlg_msg" product="default" msgid="3473883538192835204">"የ SD ካርዱ ስራ ላይነው። ማውረድ ለመፍቀድ፣ በማሳወቂያ ውስጥ \"የUSB ማከማቻ አጥፋ\" ንምረጥ።"</string>
+ <!-- no translation found for cannot_download (8150552478556798780) -->
+ <skip />
+ <string name="download_no_application_title" msgid="1286056729168874295">"ፋይል መክፈት አልተቻለም"</string>
+ <!-- no translation found for retry (1835923075542266721) -->
+ <skip />
+ <!-- no translation found for no_downloads (3947445710685021498) -->
+ <skip />
+ <!-- no translation found for download_error (413496839831257187) -->
+ <skip />
+ <!-- no translation found for download_success (2279041638155595203) -->
+ <skip />
+ <!-- no translation found for download_running (2622942231322015059) -->
+ <skip />
+ <!-- no translation found for download_pending (2599683668575349559) -->
+ <skip />
+ <!-- no translation found for download_pending_network (6548714525679461053) -->
+ <skip />
+ <!-- no translation found for download_running_paused (6418029352085656495) -->
+ <skip />
+ <!-- no translation found for download_canceled (6057083743144492515) -->
+ <skip />
+ <string name="download_not_acceptable" msgid="313769696131563652">"ማውረድ አልተቻለም።ይዘቱ በዚህ ስልክ ላይ አይታገዝም።"</string>
+ <!-- no translation found for download_file_error (1206648050615176113) -->
+ <skip />
+ <!-- no translation found for download_length_required (9038605488460437406) -->
+ <skip />
+ <!-- no translation found for download_precondition_failed (8327584102874295580) -->
+ <skip />
+ <string name="search_the_web" msgid="6046130189241962337">"ድሩን ፈልግ"</string>
+ <string name="webstorage_outofspace_notification_title" msgid="1160474608059771788">"የአሳሽ ማከማቻ ሙሉ ነው"</string>
+ <string name="webstorage_outofspace_notification_text" msgid="7341075135051829692">"ቦታ ነፃ ለማድረግ ጠቅ አድርግ።"</string>
+ <string name="webstorage_clear_data_title" msgid="689484577124333977">"የተከማቸ ውሂብ አጥራ"</string>
+ <string name="webstorage_clear_data_dialog_title" msgid="345457466368974706">"የተከማቸ ውሂብ አጥራ"</string>
+ <string name="webstorage_clear_data_dialog_message" msgid="6678281256970470125">"በዚህ ድረ ገፅ የተከማቹ ውሂቦች ሁሉ ይሰረዛሉ"</string>
+ <string name="webstorage_clear_data_dialog_ok_button" msgid="2516563534211898636">"ሁሉንም አፅዳ"</string>
+ <string name="webstorage_clear_data_dialog_cancel_button" msgid="2028867751958942762">"ይቅር"</string>
+ <string name="webstorage_origin_summary_mb_stored" msgid="1985885826292236210">"ስልክዎ ላይ MB ተከማችቷል"</string>
+ <string name="loading_video" msgid="4887871585216091096">"ቪዲዮ በማስገባት ላይ"</string>
+ <string name="geolocation_permissions_prompt_message" msgid="356796102004052471">"<xliff:g id="WEBSITE_ORIGIN">%s</xliff:g> ያሉበትን ሥፍራ ለማወቅ ይፈልጋሉ"</string>
+ <string name="geolocation_permissions_prompt_share" msgid="9084486342048347976">"ሥፍራ አጋራ"</string>
+ <string name="geolocation_permissions_prompt_dont_share" msgid="6303025160237860300">"አለመቀበል"</string>
+ <string name="geolocation_permissions_prompt_remember" msgid="3118526300707348308">"ምርጫ አስታውስ"</string>
+ <string name="geolocation_permissions_prompt_toast_allowed" msgid="987286072035125498">"ይህ ስፍራዎን መድረስ ይችላል። ቅንብሮች ውስጥ ይህን ለውጥ-> ድረ ገፅ ቅንብሮች"</string>
+ <string name="geolocation_permissions_prompt_toast_disallowed" msgid="7695100950212692515">"ይህ ስፍራዎን መድረስ አይችልም። ቅንብሮች ውስጥ ይህን ለውጥ-> ድረ ገፅ ቅንብሮች"</string>
+ <string name="geolocation_settings_page_title" msgid="1745477985097536528">"የስፍራ መድረሻ አፅዳ"</string>
+ <string name="geolocation_settings_page_summary_allowed" msgid="9180251524290811398">"ይህ ድረ ገፅ በአሁኑ ጊዜ የእርስዎን ስፍራ መድረስ ይችላል"</string>
+ <string name="geolocation_settings_page_summary_not_allowed" msgid="4589649082203102544">"ይህ ድረ ገፅ በአሁኑ ጊዜ የእርስዎን ስፍራ መድረስ ይችላል"</string>
+ <string name="geolocation_settings_page_dialog_title" msgid="1549842043381347668">"የስፍራ መድረሻ አፅዳ"</string>
+ <string name="geolocation_settings_page_dialog_message" msgid="7586671987576403993">"ለዚህ ድረ ገፅ የሥፍራ ድረስ ይጠራል"</string>
+ <string name="geolocation_settings_page_dialog_ok_button" msgid="4789434178048077287">"መዳረሻውን አጥራ"</string>
+ <string name="geolocation_settings_page_dialog_cancel_button" msgid="7941036504673409747">"ይቅር"</string>
+ <string name="website_settings_clear_all" msgid="8739804325997655980">"ሁሉንም አፅዳ"</string>
+ <string name="website_settings_clear_all_dialog_title" msgid="7791826325122461718">"የድረ ገፅ ቅንብሮችን ሁሉ ይጥሩ?"</string>
+ <string name="website_settings_clear_all_dialog_message" msgid="6150502090601476333">"ሁሉም የድረ ገፅ ውሂብ እና የሥፍራ ፍቃዶች ይሰረዛሉ።"</string>
+ <string name="website_settings_clear_all_dialog_ok_button" msgid="6401582240627669431">"ሁሉንም ውሂብ ሰርዝ"</string>
+ <string name="website_settings_clear_all_dialog_cancel_button" msgid="1896757051856611674">"ይቅር"</string>
+ <string name="progress_dialog_setting_wallpaper" msgid="4871900779338536674">"ልጥፍ በማቀናበር ላይ...."</string>
+ <string name="defaultBookmarksUpButton" msgid="2303951020715704735">"እልባቶች"</string>
+ <string name="empty_bookmarks_folder" msgid="7843361614634930942">"ምንም እልባቶች የሉም"</string>
+ <string name="rlz_access_point" msgid="7165847807377650632">"y1"</string>
+ <!-- no translation found for account_chooser_dialog_title (3314204833188808194) -->
+ <!-- no translation found for account_chooser_dialog_title (4833571985009544332) -->
+ <skip />
+ <string name="import_bookmarks_dialog_title" msgid="3325557652271172128">"ከGoogle መለያ ጋር አሳምር"</string>
+ <!-- outdated translation 2187665745413495303 --> <string name="import_bookmarks_dialog_description" msgid="1942452375564381488">"የAndroid እልባቶችዎ ከGoogle መለያ ጋር አልተጎዳኘም"</string>
+ <!-- no translation found for import_bookmarks_dialog_select_add_account (3102882579089291099) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_delete_select_account (5192284761080626386) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_delete (8854001080444749211) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_add (5433677293195372675) -->
+ <skip />
+ <!-- outdated translation 8105572409059113340 --> <string name="import_bookmarks_dialog_remove" msgid="5984607822851800902">"የAndroid እልባቶችዎን ያስወግዱ"</string>
+ <!-- no translation found for import_bookmarks_wizard_next (7578143961884352676) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_previous (8551440353688257031) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_cancel (4936061122806506634) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_done (1446247092194489191) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_add (7552306756868669353) -->
+ <skip />
+ <string name="import_bookmarks_dialog_import" msgid="6933613853573899218">"Android እልባቶችዎን ለ<xliff:g id="GOOGLE_ACCOUNT">%s</xliff:g> እልባቶች አክል"</string>
+ <!-- no translation found for menu_share_url (5851814357333739700) -->
+ <skip />
+ <!-- no translation found for max_tabs_warning (4122034303809457570) -->
+ <skip />
+ <!-- no translation found for instant_search_label (8769284297650716935) -->
+ <skip />
+ <!-- no translation found for recover_title (8095611702406163360) -->
+ <skip />
+ <!-- no translation found for recover_prompt (5526783279696786755) -->
+ <skip />
+ <!-- no translation found for recover_yes (5837971910598069183) -->
+ <skip />
+ <!-- no translation found for recover_no (3121030267940592611) -->
+ <skip />
+ <!-- no translation found for preview (1470306351083271066) -->
+ <skip />
+ <!-- no translation found for local_bookmarks (533816851415228520) -->
+ <skip />
+</resources>
diff --git a/res/values-ar-sw600dp/strings.xml b/res/values-ar-sw600dp/strings.xml
index 8d2178f..1ed9ab8 100644
--- a/res/values-ar-sw600dp/strings.xml
+++ b/res/values-ar-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"فتح في علامة تبويب جديدة في الخلفية"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"فتح الكل في علامات تبويب جديدة"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"فتح علامات تبويب جديدة وراء علامة التبويب الحالية"</string>
+ <string name="recover_title" msgid="1558775426269800998">"هل تريد استعادة علامات التبويب؟"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"يبدو أن المتصفح قد تعطل. هل تريد استعادة علامات التبويب من المرة السابقة؟"</string>
</resources>
diff --git a/res/values-ar-xlarge/strings.xml b/res/values-ar-xlarge/strings.xml
index db12504..e9c0109 100644
--- a/res/values-ar-xlarge/strings.xml
+++ b/res/values-ar-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"فتح في علامة تبويب جديدة في الخلفية"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"فتح الكل في علامات تبويب جديدة"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"فتح علامات تبويب جديدة وراء علامة التبويب الحالية"</string>
+ <string name="recover_title" msgid="7754049918641251703">"استعادة علامات التبويب؟"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"يبدو أن المتصفح قد تعطل. هل تريد استعادة علامات التبويب من المرة السابقة؟"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 98d59bd..8a06c71 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"موافق"</string>
<string name="do_not_save" msgid="6777633870113477714">"إلغاء"</string>
<string name="location" msgid="3411848697912600125">"العنوان"</string>
+ <string name="account" msgid="5179824606448077042">"الحساب"</string>
<string name="containing_folder" msgid="6771180232953030479">"إضافة إلى"</string>
<string name="new_folder" msgid="7743540149088867917">"مجلد جديد"</string>
<string name="edit_folder" msgid="621817453133656156">"تعديل مجلد"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"إدخال وحفظ البيانات لملء حقول نموذج الويب تلقائيًا"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"تسجيل الدخول تلقائيًا إلى Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"تسجيل الدخول إلى مواقع Google باستخدام <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"تسجل الدخول التلقائي متاح."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"تسجيل الدخول كـ"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"تسجيل الدخول"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"إخفاء"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"أخفق تسجيل الدخول."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"أدخل البيانات المراد ملؤها تلقائيًا في حقول الويب عندما تلمسها."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"الاسم بالكامل:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"ضخم"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"حجم النص"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"الحد الأدنى لحجم الخط"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"فرض تمكين التكبير/التصغير"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"تجاوز طلب موقع الويب للتحكم في سلوك التكبير/التصغير"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"التكبير/التصغير الافتراضي"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"بعيد"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"الكورية (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"تشفير النص"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"إمكانية الدخول"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"الميزات الاختبارية"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"عناصر التحكم السريعة"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"مرر الإبهام من الحافة اليسرى أو اليمنى للدخول إلى عناصر التحكم السريعة وإخفاء أشرطة عناوين URL والتطبيق"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"تعرض صفحتك الرئيسية مواقع الويب الأكثر زيارة."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"بحث Google الفوري"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"استخدم بحث Google الفوري عندما تستخدم بحث Google, لإظهار النتائج أثناء الكتابة (يمكن أن يزيد ذلك من استخدام البيانات)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"ملء الشاشة"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"استخدم وضع ملء الشاشة لإخفاء شريط الحالة."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"مبدّل وكيل المستخدم"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"التبديل بين إصداري الجهاز اللوحي وسطح المكتب لأحد المواقع"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"انقر على Android أو رمز الكمبيوتر المحمول للتبديل بين إصداري الجهاز اللوحي وسطح المكتب من الموقع."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"مشكلة في اتصال البيانات"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"مشكلة في الملف"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"تأكيد"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"مشاركة"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"لا يتوفر المزيد من علامات التبويب"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google مع البحث الفوري (ميزات اختبارية)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"استعادة النوافذ؟"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"يبدو أن المتصفح قد تعطل. هل تريد استعادة النوافذ من المرة السابقة؟"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"نعم"</string>
+ <string name="recover_no" msgid="3121030267940592611">"لا"</string>
+ <string name="preview" msgid="1470306351083271066">"المعاينة:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"محلية"</string>
</resources>
diff --git a/res/values-bg-sw600dp/strings.xml b/res/values-bg-sw600dp/strings.xml
index 360437b..19f9ba8 100644
--- a/res/values-bg-sw600dp/strings.xml
+++ b/res/values-bg-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Отваряне в нов раздел на заден план"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Отваряне на всички в нови раздели"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Отваряне на нови раздели зад текущия"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Да се възстановят ли разделите?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Изглежда се получи срив в браузъра. Искате ли да възстановите разделите си от последния път?"</string>
</resources>
diff --git a/res/values-bg-xlarge/strings.xml b/res/values-bg-xlarge/strings.xml
index 91bd88b..ea2a21c 100644
--- a/res/values-bg-xlarge/strings.xml
+++ b/res/values-bg-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Отваряне в нов раздел на заден план"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Отваряне на всички в нови раздели"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Отваряне на нови раздели зад текущия"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Да се възстановят ли разделите?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Изглежда се получи срив в браузъра. Искате ли да възстановите разделите си от последния път?"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index d4f727b..2842e52 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Отказ"</string>
<string name="location" msgid="3411848697912600125">"Адрес"</string>
+ <string name="account" msgid="5179824606448077042">"Профил"</string>
<string name="containing_folder" msgid="6771180232953030479">"Добавяне към"</string>
<string name="new_folder" msgid="7743540149088867917">"Нова папка"</string>
<string name="edit_folder" msgid="621817453133656156">"Редактиране на папката"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Въведете и запазете данни за автоматично попълване на полетата в уеб формуляри"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Автоматичен вход в Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Влизате в сайтове на Google посредством <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Автоматичният вход е налице."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Влезте като"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Вход"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Скриване"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Влизането не бе успешно."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Въведете данните, които при докосване искате да се попълнят автоматично в уеб полетата."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Пълно име:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Огромен"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Размер на текста"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Минимален размер на шрифта"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Принудит. активиране на мащаба"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Дали заявката на сайт за контрол на мащаба да се отхвърли, или не"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Стандартна промяна на мащаба"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Далече"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Корейски (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Текстово кодиране"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Достъпност"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Лаборатория"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Бързи контроли"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Прокарайте палец от левия/десния край за достъп до бързите контроли и скр. на лентите за прил. и URL адр."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Началната ви страница показва най-посещаваните от вас уеб страници."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Динамично търсене"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Използвайте Google Динамично търсене, за да се показват резултати, докато пишете (може да увеличи употребата на данни)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Цял екран"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Използване на режима на цял екран за скриване на лентата на състоянието."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Превключвател на потребителски агенти"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Превключване между версията за таблет и настолен компютър на даден сайт"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Докоснете иконата на Android или на лаптоп, за да превключвате между версията за таблет и настолен компютър на даден сайт."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Проблем с обмен на данни"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Проблем с файла"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Потвърждаване"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Споделяне"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Не се предлагат повече раздели"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google с Динамично търсене (Лаборатория)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Да се възстановят ли прозорците?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Изглежда се получи срив в браузъра. Искате ли да възстановите прозорците си от последния път?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Да"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Не"</string>
+ <string name="preview" msgid="1470306351083271066">"Визуализация:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Локални"</string>
</resources>
diff --git a/res/values-ca-sw600dp/strings.xml b/res/values-ca-sw600dp/strings.xml
index 2ae7b26..936ba60 100644
--- a/res/values-ca-sw600dp/strings.xml
+++ b/res/values-ca-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Obre en una pestanya de fons nova"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Obre-ho tot en pestanyes noves"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Obre les pestanyes noves darrere l\'actual"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vols restaurar les pestanyes?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Sembla que s\'ha bloquejat el navegador. Vols restaurar les pestanyes des de la darrera vegada?"</string>
</resources>
diff --git a/res/values-ca-xlarge/strings.xml b/res/values-ca-xlarge/strings.xml
index 783e2f4..6d41d51 100644
--- a/res/values-ca-xlarge/strings.xml
+++ b/res/values-ca-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Obre en una pestanya de fons nova"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Obre-ho tot en pestanyes noves"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Obre les pestanyes noves darrere l\'actual"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vols restaurar les pestanyes?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Sembla que s\'ha bloquejat el navegador. Vols restaurar les pestanyes que tenies obertes la darrera vegada?"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 4071fed..fed5f87 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"D\'acord"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancel·la"</string>
<string name="location" msgid="3411848697912600125">"Adreça"</string>
+ <string name="account" msgid="5179824606448077042">"Compte"</string>
<string name="containing_folder" msgid="6771180232953030479">"Afegeix a"</string>
<string name="new_folder" msgid="7743540149088867917">"Nova carpeta"</string>
<string name="edit_folder" msgid="621817453133656156">"Edita la carpeta"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Introdueix i desa les dades per emplenar automàticament els camps del formulari web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Inici sessió automàtic a Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Inici de la sessió a Llocs web de Google amb <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Inici de sessió automàtic disponible."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Inicia la sessió com a"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Inici sessió"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Amaga"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Error en iniciar sessió."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Introdueix les dades que vulguis que s\'emplenin automàticament als camps web quan els toquis."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nom complet:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Enorme"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Mida del text"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Cos de lletra mínim"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Força l\'activació del zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Decideix si vols substituir o no la sol·licitud d\'un lloc web per controlar el comportament del zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predeterminat"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lluny"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreà (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificació del text"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accessibilitat"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controls ràpids"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Fes lliscar el polze des de la vora esquerra o dreta per accedir als controls ràpids i ocultar les barres d\'aplicació i URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"La teva pàgina d\'inici mostra les pàgines web que més visites."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Utilitza Google Instant quan utilitzis la Cerca de Google per mostrar resultats mentre escrius (augmenta l\'ús de dades)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Pantalla completa"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Utilitza el mode de pantalla completa per amagar la barra d\'estat."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Commutador d\'agent d\'usuari"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Canvia entre la versió per a tauleta i la versió per a escriptori d\'un lloc"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Pica la icona d\'Android o la del portàtil per passar de la versió per a tauleta a la versió per a escriptori d\'un lloc."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema de connectivitat de dades"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problema amb el fitxer"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirma"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Comparteix"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"No hi ha cap més pestanya disponible"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google amb Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vols restaurar les finestres?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Sembla que s\'ha bloquejat el navegador. Vols restaurar les finestres que tenies obertes la darrera vegada?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sí"</string>
+ <string name="recover_no" msgid="3121030267940592611">"No"</string>
+ <string name="preview" msgid="1470306351083271066">"Visualització prèvia:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Local"</string>
</resources>
diff --git a/res/values-cs-sw600dp/strings.xml b/res/values-cs-sw600dp/strings.xml
index abca150..d965e71 100644
--- a/res/values-cs-sw600dp/strings.xml
+++ b/res/values-cs-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Otevřít na nové kartě na pozadí"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Otevřít vše na nových kartách"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Otevírat nové karty za aktuální kartou"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Obnovit karty?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Zřejmě došlo k selhání prohlížeče. Chcete obnovit naposledy otevřené karty?"</string>
</resources>
diff --git a/res/values-cs-xlarge/strings.xml b/res/values-cs-xlarge/strings.xml
index 9f47093..25bdce9 100644
--- a/res/values-cs-xlarge/strings.xml
+++ b/res/values-cs-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Otevřít na nové kartě na pozadí"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Otevřít vše na nových kartách"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Otevírat nové karty za aktuální kartou"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Obnovit karty?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Zřejmě došlo k selhání prohlížeče. Chcete obnovit naposledy otevřené karty?"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 34def37..9f0681d 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Zrušit"</string>
<string name="location" msgid="3411848697912600125">"Adresa"</string>
+ <string name="account" msgid="5179824606448077042">"Účet"</string>
<string name="containing_folder" msgid="6771180232953030479">"Přidat do složky"</string>
<string name="new_folder" msgid="7743540149088867917">"Nová složka"</string>
<string name="edit_folder" msgid="621817453133656156">"Upravit složku"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Zadat a uložit údaje pro automatické vyplnění polí webových formulářů"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatické přihlášení do Googlu"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Přihlašování do webů Google pomocí uživatelského jména <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatické přihlašování je k dispozici."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Přihlásit se jako"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Přihlášení"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Skrýt"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Přihlášení selhalo."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Zadejte data, která chcete automaticky vyplňovat do textových polí na webu, když se jich dotknete."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Jméno a příjmení:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Velmi velký"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Velikost textu"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimální velikost písma"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Vynutit aktivaci přiblížení"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Zda přepsat požadavek webu na řízení funkce přiblížení, či nikoliv"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Výchozí přiblížení"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Daleko"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korejština (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Kódování textu"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Usnadnění"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laboratoř Google"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Rychlé ovládací prvky"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Posunutím prstu od levého nebo pravého okraje zobrazíte rychlé ovládací prvky a skryjete panely aplikací a URL."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Na vaší domovské stránce se zobrazují nejnavštěvovanější webové stránky."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Dynamické vyhledávání Google"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Dynamické vyhledávání ve Vyhledávání Google zobrazuje výsledky již při zadávání dotazu. (Může se zvýšit množství přenesených dat.)"</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Celá obrazovka"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Chcete-li skrýt stavový řádek, použijte režim zobrazení na celou obrazovku."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Přepínač identifikátoru user-agent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Přepínání mezi verzí webových stránek pro tablety a verzí pro počítače."</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Klepnutím na ikonu platformy Android nebo laptopu můžete přepínat mezi verzí webových stránek pro tablety a verzí pro počítače."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problémy s datovým připojením"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problém se souborem"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Potvrdit"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Sdílet"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Žádné další karty nejsou k dispozici"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google s dynamickým vyhledáváním (experimentální funkce)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Obnovit okna?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Zřejmě došlo k selhání prohlížeče. Chcete obnovit naposledy otevřená okna?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ano"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Ne"</string>
+ <string name="preview" msgid="1470306351083271066">"Náhled:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokální"</string>
</resources>
diff --git a/res/values-da-sw600dp/strings.xml b/res/values-da-sw600dp/strings.xml
index 0f5663b..5d0eda5 100644
--- a/res/values-da-sw600dp/strings.xml
+++ b/res/values-da-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Åbn på ny fane i baggrunden"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Åbn alle på nye faner"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Åbn nye faner bag den aktuelle"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vil du gendanne faner?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Det lader til, at browseren er gået ned. Vil du gendanne dine faner fra sidste gang?"</string>
</resources>
diff --git a/res/values-da-xlarge/strings.xml b/res/values-da-xlarge/strings.xml
index ab581c7..43867bb 100644
--- a/res/values-da-xlarge/strings.xml
+++ b/res/values-da-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Åbn på ny fane i baggrunden"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Åbn alle i nye faner"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Åbn nye faner bag den aktive"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vil du gendanne fanerne?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Det lader til, at browseren er gået ned. Vil du gendanne dine faner fra sidste gang?"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index c0647c7..560665d 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Annuller"</string>
<string name="location" msgid="3411848697912600125">"Adresse"</string>
+ <string name="account" msgid="5179824606448077042">"Konto"</string>
<string name="containing_folder" msgid="6771180232953030479">"Føj til"</string>
<string name="new_folder" msgid="7743540149088867917">"Ny mappe"</string>
<string name="edit_folder" msgid="621817453133656156">"Rediger mappen"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Indtast og gem data til autoudfyldning af felter i webformularer"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatisk Google-login"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Logger ind på Google-websteder med <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatisk login er tilgængelig."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Log ind som"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Log ind"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Skjul"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Login mislykkedes."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Angiv de data, der skal udfyldes automatisk i webfelter, når du trykker på dem."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Fulde navn:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Kæmpestor"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tekststørrelse"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Mindste skriftstørrelse"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Tving aktivering af zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Tilsidesættelse af et websteds anmodning om kontrol af zoomadfærd"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Standardzoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Langt væk"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Koreansk (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Tekstkodning"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Tilgængelighed"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Hurtig betjening"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Glid fra venstre til højre for hurtig betjening og for at skjule applikation og adresselinje"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Din startside viser dine mest besøgte websider."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Direkte"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Brug Google Direkte, når du søger på Google for at få vist resultater ved indtastning (kan forøge dataforbruget)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Fuld skærm"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Brug fuldskærmstilstand til at skjule statuslinjen."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Brugeragenten Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Skift mellem tablet- og computerudgaver af et websted"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tryk på ikonet for Android eller bærbar for at skifte mellem tablet- og computerudgaver af et websted."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Dataforbindelsesproblem"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Der er et problem med filen"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Bekræft"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Del"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Der er ikke flere tilgængelige faner"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google med Direkte (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vil du gendanne vinduer?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Det lader til, at browseren er gået ned. Vil du gendanne dine vinduer fra sidste gang?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ja"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nej"</string>
+ <string name="preview" msgid="1470306351083271066">"Vis eksempel:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokal"</string>
</resources>
diff --git a/res/values-de-sw600dp/strings.xml b/res/values-de-sw600dp/strings.xml
index 10c7f40..3b22054 100644
--- a/res/values-de-sw600dp/strings.xml
+++ b/res/values-de-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"In neuem Hintergrundtab öffnen"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Alle in jeweils neuem Tab öffnen"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Neue Tabs hinter aktuellem Tab öffnen"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Tabs wiederherstellen?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Offenbar ist der Browser abgestürzt. Sollen Ihre zuletzt geöffneten Tabs wiederhergestellt werden?"</string>
</resources>
diff --git a/res/values-de-xlarge/strings.xml b/res/values-de-xlarge/strings.xml
index 71c5fa3..9135940 100644
--- a/res/values-de-xlarge/strings.xml
+++ b/res/values-de-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"In neuem Hintergrundtab öffnen"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Alle in jeweils neuem Tab öffnen"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Neue Tabs hinter dem aktuellen Tab öffnen"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Tabs wiederherstellen?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Offenbar ist der Browser abgestürzt. Sollen Ihre Tabs wiederhergestellt werden?"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 7ffc171..e9652c2 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Abbrechen"</string>
<string name="location" msgid="3411848697912600125">"Adresse"</string>
+ <string name="account" msgid="5179824606448077042">"Konto"</string>
<string name="containing_folder" msgid="6771180232953030479">"Hinzufügen zu"</string>
<string name="new_folder" msgid="7743540149088867917">"Neuer Ordner"</string>
<string name="edit_folder" msgid="621817453133656156">"Ordner bearbeiten"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Eingabe und Speichern von Daten für automatisch auszufüllende Webformularfelder"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatische Google-Anmeldung"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Anmeldung in Google Sites mit <xliff:g id="ID_1">%s</xliff:g>..."</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatische Anmeldung ist verfügbar."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Anmelden als"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Anmelden"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ausblenden"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Anmeldung fehlgeschlagen"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Geben Sie die Daten ein, die automatisch in Web-Felder eingetragen werden sollen, wenn Sie sie berühren."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Vollständiger Name:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Sehr groß"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Textgröße"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Mindestschriftgröße"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Zoom zwingend aktivieren"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Anfrage einer Website zur Steuerung des Zoomverhaltens überschreiben?"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Standard-Zoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Entfernt"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Koreanisch (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Textcodierung"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Eingabehilfen"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Schnellsteuerung"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Für Schnellsteuerung/Ausblenden der App- und URL-Leisten Daumen von links nach rechts ziehen"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Auf Ihrer Startseite werden Ihre am häufigsten besuchten Webseiten angezeigt."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Nutzen Sie Google Instant bei der Google-Suche. Ergebnisse werden bei Eingabe angezeigt - ggf. mehr Speicher erforderlich."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Vollbild"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Vollbildmodus zum Ausblenden der Statusleiste verwenden"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"User-Agent-Wechsler"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Zwischen den Tablet- und Desktop-Versionen einer Website wechseln"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tippen Sie auf das Android- oder Laptop-Symbol, um zwischen den Tablet- und Desktop-Versionen einer Website zu wechseln."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Datenverbindungsproblem"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem mit Datei"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Bestätigen"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Weitergeben"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Es sind keine weiteren Tabs verfügbar."</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google mit dynamischer Suche (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Fenster wiederherstellen?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Offenbar ist der Browser abgestürzt. Sollen Ihre Fenster wiederhergestellt werden?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ja"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nein"</string>
+ <string name="preview" msgid="1470306351083271066">"Vorschau:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokal"</string>
</resources>
diff --git a/res/values-el-sw600dp/strings.xml b/res/values-el-sw600dp/strings.xml
index 053daf3..aa979be 100644
--- a/res/values-el-sw600dp/strings.xml
+++ b/res/values-el-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Άνοιγμα σε νέα καρτέλα στο παρασκήνιο"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Άνοιγμα όλων σε νέες καρτέλες"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Άνοιγμα νέων καρτελών πίσω από την τρέχουσα"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Επαναφορά καρτελών;"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Παρουσιάστηκε σφάλμα στη λειτουργία του προγράμματος περιήγησης. Θα θέλατε να επαναφέρετε τις καρτέλες από την προηγούμενη συνεδρία σας;"</string>
</resources>
diff --git a/res/values-el-xlarge/strings.xml b/res/values-el-xlarge/strings.xml
index 17411be..de581b8 100644
--- a/res/values-el-xlarge/strings.xml
+++ b/res/values-el-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Άνοιγμα σε νέα καρτέλα στο παρασκήνιο"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Άνοιγμα όλων σε νέες καρτέλες"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Άνοιγμα νέων καρτελών πίσω από την τρέχουσα"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Επαναφορά καρτελών;"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Η λειτουργία του προγράμματος περιήγησης διακόπηκε ξαφνικά. Θα θέλατε να κάνετε ανάκτηση των καρτελών από την τελευταία συνεδρία σας;"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 297eb46..8fde408 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Ακύρωση"</string>
<string name="location" msgid="3411848697912600125">"Διεύθυνση"</string>
+ <string name="account" msgid="5179824606448077042">"Λογαριασμός"</string>
<string name="containing_folder" msgid="6771180232953030479">"Προσθήκη σε"</string>
<string name="new_folder" msgid="7743540149088867917">"Νέος φάκελος"</string>
<string name="edit_folder" msgid="621817453133656156">"Επεξεργασία φακέλου"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Καταχώριση και αποθήκευση δεδομένων για πεδία φόρμας ιστού αυτόματης συμπλήρωσης"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Αυτόματη σύνδεση στο Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Συνδεθείτε σε Ιστότοπους Google χρησιμοποιώντας το <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Διαθέσιμη αυτόματη σύνδεση."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Σύνδεση ως"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Σύνδεση"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Απόκρυψη"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Η σύνδεση απέτυχε."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Καταχωρίστε τα δεδομένα που θέλετε για να κάνετε αυτόματη συμπλήρωση των πεδίων ιστού όταν τα αγγίζετε,"</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Πλήρες όνομα:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Πολύ μεγάλο"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Μέγεθος κειμένου"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Ελάχιστο μέγ. γραμματοσειράς"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Αναγκ. ενεργοπ. εστίασης"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Να αντικατ. ή όχι το αίτημα ιστότ. για έλεγχο συμπερ. εστίασης"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Προεπιλεγμένο ζουμ"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Μακριά"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Κορεατικά (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Κωδικοποίηση κειμένου"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Προσβασιμότητα"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Εργαστήρια"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Στοιχεία γρήγορου ελέγχου"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Σύρετε τον αντίχειρα από αρ. ή δεξ. για τα στοιχ. γρήγ. ελέγχου και κρύψτε τις γραμμές Εφαρμογές και URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Η αρχική σελίδα εμφανίζει τις ιστοσελίδες με τις περισσότερες επισκέψεις σας."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Χρησιμοποιήστε το Instant μαζί με την Αναζήτηση για να εμφανίζονται αποτελ. καθώς πληκτρολ. (πιθανή αύξηση δεδομένων)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Πλήρης οθόνη"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Χρησιμοποιήστε τη λειτουργία πλήρους οθόνης για την απόκρυψη της γραμμής κατάστασης."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Εναλλαγή παράγοντα χρήστη"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Κάντε εναλλαγή μεταξύ των εκδόσεων ενός ιστότοπου για tablet και για κανονικό υπολογιστή"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Πατήστε στο εικονίδιο Android ή στο εικονίδιο φορητού υπολογιστή για να κάνετε εναλλαγή μεταξύ των εκδόσεων ενός ιστότοπου για tablet και για κανονικό υπολογιστή."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Πρόβλημα σύνδεσης δεδομένων"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Υπάρχει πρόβλημα με το αρχείο"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Επιβεβαίωση"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Κοινή χρήση"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Δεν υπάρχουν άλλες διαθέσιμες καρτέλες"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google με Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Επαναφορά παραθύρων;"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Η λειτουργία του προγράμματος περιήγησης διακόπηκε ξαφνικά. Θα θέλατε να κάνετε ανάκτηση των παραθύρων από την τελευταία συνεδρία σας;"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ναι"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Όχι"</string>
+ <string name="preview" msgid="1470306351083271066">"Προεπισκόπηση:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Τοπικά"</string>
</resources>
diff --git a/res/values-en-rGB-sw600dp/strings.xml b/res/values-en-rGB-sw600dp/strings.xml
index 71f9866..fc9cd2e 100644
--- a/res/values-en-rGB-sw600dp/strings.xml
+++ b/res/values-en-rGB-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Open in new background tab"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Open all in new tabs"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Open new tabs behind the current one"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Restore tabs?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Browser appears to have crashed. Would you like to restore the tabs from your last session?"</string>
</resources>
diff --git a/res/values-en-rGB-xlarge/strings.xml b/res/values-en-rGB-xlarge/strings.xml
index ee70575..1db7634 100644
--- a/res/values-en-rGB-xlarge/strings.xml
+++ b/res/values-en-rGB-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Open in new background tab"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Open all in new tabs"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Open new tabs behind the current one"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Restore tabs?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Browser appears to have crashed. Would you like to restore your tabs from last time?"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index e8c0538..1ae0684 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancel"</string>
<string name="location" msgid="3411848697912600125">"Address"</string>
+ <string name="account" msgid="5179824606448077042">"Account"</string>
<string name="containing_folder" msgid="6771180232953030479">"Add to"</string>
<string name="new_folder" msgid="7743540149088867917">"New folder"</string>
<string name="edit_folder" msgid="621817453133656156">"Edit folder"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Enter and save data for auto-filling web form fields"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatic Google sign-in"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Signing in to Google sites using <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatic sign-in is available."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Sign in as"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Login"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Hide"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Login failed."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Enter the data that you want to auto-fill in web fields when you touch them."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Full name:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Huge"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Text size"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimum font size"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Force enable zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Whether or not to override a website\'s request to control zoom behaviour"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Default zoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Far"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korean (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Text encoding"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accessibility"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Quick controls"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Swipe thumb from left or right edge to access quick controls and hide Application and URL bars"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Your homepage displays your most-visited web pages."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Use Google Instant when you use Google Search, to show results as you type (this can increase data use)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Full screen"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Use full-screen mode to hide the status bar."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Toggle between the tablet and desktop versions of a site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tap on the Android or laptop icon to toggle between the tablet and desktop versions of a site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Data connectivity problem"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem with file"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirm"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Share"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"No more tabs available"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google with Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Restore windows?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Browser appears to have crashed. Would you like to restore your windows from last time?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Yes"</string>
+ <string name="recover_no" msgid="3121030267940592611">"No"</string>
+ <string name="preview" msgid="1470306351083271066">"Preview:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Local"</string>
</resources>
diff --git a/res/values-es-rUS-sw600dp/strings.xml b/res/values-es-rUS-sw600dp/strings.xml
index bf713c5..eae4582 100644
--- a/res/values-es-rUS-sw600dp/strings.xml
+++ b/res/values-es-rUS-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Abrir vínculo en una nueva pestaña en segundo plano"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Abrir todos en nuevas pestañas"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Abrir las nuevas pestañas detrás de la pestaña actual"</string>
+ <string name="recover_title" msgid="1558775426269800998">"¿Deseas restaurar las pestañas?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Parece que el navegador se bloqueó. ¿Deseas restaurar las últimas pestañas que abriste?"</string>
</resources>
diff --git a/res/values-es-rUS-xlarge/strings.xml b/res/values-es-rUS-xlarge/strings.xml
index 096451d..f9d14cd 100644
--- a/res/values-es-rUS-xlarge/strings.xml
+++ b/res/values-es-rUS-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Abrir en una nueva pestaña de fondo"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Abrir todos en pestañas nuevas"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Abrir nuevas pestañas detrás de la actual"</string>
+ <string name="recover_title" msgid="7754049918641251703">"¿Quieres restaurar las pestañas?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Parece que se ha producido un fallo en el navegador. ¿Quieres restaurar las pestañas de la última sesión?"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 6b5c40a..5ceb8cf 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Aceptar"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancelar"</string>
<string name="location" msgid="3411848697912600125">"Dirección"</string>
+ <string name="account" msgid="5179824606448077042">"Cuenta"</string>
<string name="containing_folder" msgid="6771180232953030479">"Agregar a"</string>
<string name="new_folder" msgid="7743540149088867917">"Carpeta nueva"</string>
<string name="edit_folder" msgid="621817453133656156">"Editar carpeta"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Ingresa y guarda datos para completar campos de formularios web automáticamente."</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Acceso automático a Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Accediendo a Google Sites utilizando <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Acceso automático disponible"</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Iniciar sesión como"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Acceder"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ocultar"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Falló el acceso."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Ingresa los datos que deseas que se completen automáticamente al tocar los campos web."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nombre completo:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Enorme"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tamaño del texto"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Tamaño de fuente mínimo"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Obligar a habilitar el zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Anular o no la solicitud de control del comportamiento del zoom de un sitio web"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predeterminado"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lejos"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreano (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificación de texto"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accesibilidad"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controles rápidos"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Desliza pulgar de borde izq. o der. para acceder a contr. ráp. y ocultar barras Aplicación y URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Tu página principal muestra tus páginas web más visitadas."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Usa Google Instant con Búsq. de Google para que los resultados aparezcan mientras tipeas (esto puede aumentar el uso de datos)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Pantalla completa"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Usa el modo de pantalla completa para ocultar la barra de estado."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Botón de usuario-agente"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Alternar entre las versiones de tableta y de escritorio de un sitio"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Pulsa el ícono de Android o de laptop para alternar entre las versiones de tableta y de escritorio de un sitio."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema de conectividad de datos"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problema con el archivo"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirmar"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Compartir"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"No hay más pestañas disponibles."</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google con Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"¿Quieres restaurar las ventanas?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Parece que se ha producido un fallo en el navegador. ¿Quieres restaurar las ventanas de la última sesión?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sí"</string>
+ <string name="recover_no" msgid="3121030267940592611">"No"</string>
+ <string name="preview" msgid="1470306351083271066">"Vista previa:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Locales"</string>
</resources>
diff --git a/res/values-es-sw600dp/strings.xml b/res/values-es-sw600dp/strings.xml
index 87834fd..db28a42 100644
--- a/res/values-es-sw600dp/strings.xml
+++ b/res/values-es-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Abrir en una nueva pestaña en segundo plano"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Abrir todo en pestañas nuevas"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Abrir nuevas pestañas detrás de la actual"</string>
+ <string name="recover_title" msgid="1558775426269800998">"¿Restaurar pestañas?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Parece que se ha producido un error en el navegador. ¿Quieres restaurar las pestañas de la última sesión?"</string>
</resources>
diff --git a/res/values-es-xlarge/strings.xml b/res/values-es-xlarge/strings.xml
index c4bdd3e..690043d 100644
--- a/res/values-es-xlarge/strings.xml
+++ b/res/values-es-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Abrir en una nueva pestaña en segundo plano"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Abrir todo en pestañas nuevas"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Abrir nuevas pestañas detrás de la actual"</string>
+ <string name="recover_title" msgid="7754049918641251703">"¿Quieres restaurar las pestañas?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Parece que se ha producido un error en el navegador. ¿Quieres restaurar las pestañas de la última sesión?"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 5a3b439..d99e8a0 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Aceptar"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancelar"</string>
<string name="location" msgid="3411848697912600125">"Dirección"</string>
+ <string name="account" msgid="5179824606448077042">"Cuenta"</string>
<string name="containing_folder" msgid="6771180232953030479">"Añadir a"</string>
<string name="new_folder" msgid="7743540149088867917">"Nueva carpeta"</string>
<string name="edit_folder" msgid="621817453133656156">"Editar carpeta"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Introducir y guardar datos de campos de cumplimentación automática de formularios web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Acceso automático a Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Accediendo a Google Sites mediante <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"El acceso automático está disponible."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Acceder como"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Acceder"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ocultar"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Error al acceder"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Introduce los datos con los que quieres que los campos web se completen automáticamente al tocarlos."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nombre completo:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Enorme"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tamaño de texto"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Tamaño mínimo de fuente"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Forzar habilitación de zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"¿Anular control del zoom?"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predeterminado"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lejos"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreano (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificación de texto"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accesibilidad"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controles rápidos"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Desliza el pulgar para acceder a los controles rápidos y ocultar las barras."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"En la página principal se muestran las páginas web más visitadas."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Con Google Instant, aparecerán resultados de búsqueda de Google a medida que escribas (puede aumentar el uso de datos)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Pantalla completa"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Utiliza el modo de pantalla completa para ocultar la barra de estado."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Cambio de user-agent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Alternar entre las versiones para escritorio y para tablet de un sitio"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Toca el icono de portátil o de Android para alternar entre las versiones para escritorio y para tablet de un sitio web."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema de conectividad de datos"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problema con archivo"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"OK"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Compartir"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"No hay más pestañas disponibles."</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google con Instant (experimental)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"¿Quieres restaurar las ventanas?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Parece que se ha producido un error en el navegador. ¿Quieres restaurar las ventanas de la última sesión?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sí"</string>
+ <string name="recover_no" msgid="3121030267940592611">"No"</string>
+ <string name="preview" msgid="1470306351083271066">"Vista previa:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Locales"</string>
</resources>
diff --git a/res/values-fa-sw600dp/strings.xml b/res/values-fa-sw600dp/strings.xml
index b272aec..a77a15e 100644
--- a/res/values-fa-sw600dp/strings.xml
+++ b/res/values-fa-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"باز کردن در برگه جدید در پس زمینه"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"باز کردن همه در برگه های جدید"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"باز کردن برگه های جدید پشت برگه فعلی"</string>
+ <string name="recover_title" msgid="1558775426269800998">"برگه ها بازیابی شوند؟"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"به نظر می رسد مرورگر خراب شده است. آیا می خواهید برگه ها را از آخرین بازدید خود بازیابی کنید؟"</string>
</resources>
diff --git a/res/values-fa-xlarge/strings.xml b/res/values-fa-xlarge/strings.xml
index cd670ff..25a7039 100644
--- a/res/values-fa-xlarge/strings.xml
+++ b/res/values-fa-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"باز کردن در برگه جدید در پس زمینه"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"باز کردن همه در برگه های جدید"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"باز کردن برگه های جدید پشت برگه فعلی"</string>
+ <string name="recover_title" msgid="7754049918641251703">"برگه ها بازیابی شوند؟"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"به نظر می رسد مرورگر خراب شده است. آیا می خواهید برگه های آخرین بازدید خود را بازیابی کنید؟"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 4a0204a..7d0748e 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"تأیید"</string>
<string name="do_not_save" msgid="6777633870113477714">"لغو"</string>
<string name="location" msgid="3411848697912600125">"آدرس"</string>
+ <string name="account" msgid="5179824606448077042">"حساب"</string>
<string name="containing_folder" msgid="6771180232953030479">"افزودن به"</string>
<string name="new_folder" msgid="7743540149088867917">"پوشه جدید"</string>
<string name="edit_folder" msgid="621817453133656156">"ویرایشگر پوشه"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"جهت تکمیل خودکار قسمت های فرم وب، داده ها را وارد و ذخیره کنید"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"ورود به سیستم خودکار Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"ورود به سیستم سایت های Google با استفاده از <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"ورود به سیستم خودکار امکان پذیر است."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"ورود به سیستم بعنوان"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"ورود به سیستم"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"پنهان کردن"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"ورود به سیستم انجام نشد."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"داده های مورد نظر را وارد كنيد تا هنگام لمس كردن زمينه های وب، به صورت خودكار تكميل شوند."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"نام کامل:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"بسیار بزرگ"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"اندازه متن"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"حداقل اندازه قلم"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"فعال کردن اجباری بزرگنمایی"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"لغو یا عدم لغو درخواست وب سایت برای کنترل رفتار بزرگنمایی"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"بزرگنمایی پیش فرض"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"دور"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"کره ای (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"رمزگذاری متن"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"قابلیت دسترسی"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"کنترل های سریع"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"انگشت شست را از لبه چپ یا راست حرکت دهید تا به کنترل های سریع دسترسی داشته و نوارهای URL و برنامه را پنهان کنید"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"صفحات وب بیشتر بازدید شده شما در صفحه اصلی نشان داده می شود."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"هنگام استفاده از جستجوی Google، برای نمایش نتایج در حین تایپ از Google Instant استفاده کنید (ممکن است مصرف داده بالا برود)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"تمام صفحه"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"استفاده از حالت تمام صفحه برای مخفی کردن نوار وضعیت."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"بین نسخه های رایانه لوحی و رایانه رومیزی یک سایت جابجا شوید"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"برای جابجایی بین نسخه های رایانه لوحی و رایانه رومیزی یک سایت، روی نماد Android یا لپ تاپ ضربه بزنید."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"مشکل اتصال داده"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"مشکل در فایل"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"تأیید"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"اشتراک گذاری"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"برگه بیشتری در دسترس نیست"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google با Instant (ویژگی های آزمایشی)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"پنجره ها بازیابی شوند؟"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"به نظر می رسد مرورگر خراب شده است. آیا می خواهید پنجره های آخرین بازدید خود را بازیابی کنید؟"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"بله"</string>
+ <string name="recover_no" msgid="3121030267940592611">"خیر"</string>
+ <string name="preview" msgid="1470306351083271066">"پیش نمایش:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"محلی"</string>
</resources>
diff --git a/res/values-fi-sw600dp/strings.xml b/res/values-fi-sw600dp/strings.xml
index a604c93..e0ccf4c 100644
--- a/res/values-fi-sw600dp/strings.xml
+++ b/res/values-fi-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Avaa uudessa välilehdessä taustalla"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Avaa kaikki uusiin välilehtiin"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Avaa uudet välilehdet nykyisen taakse"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Palautetaanko välilehdet?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Selain vaikuttaa kaatuneen. Haluatko palauttaa viime kerralla auki olleet välilehdet?"</string>
</resources>
diff --git a/res/values-fi-xlarge/strings.xml b/res/values-fi-xlarge/strings.xml
index a1246d4..850cab4 100644
--- a/res/values-fi-xlarge/strings.xml
+++ b/res/values-fi-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Avaa uudessa välilehdessä taustalla"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Avaa kaikki uusiin välilehtiin"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Avaa uudet välilehdet nykyisen taakse"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Palautetaanko välilehdet?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Selain vaikuttaa kaatuneen. Haluatko palauttaa viime kerralla auki olleet välilehdet?"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index f14f718..1863e3a 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Peruuta"</string>
<string name="location" msgid="3411848697912600125">"Osoite"</string>
+ <string name="account" msgid="5179824606448077042">"Tili"</string>
<string name="containing_folder" msgid="6771180232953030479">"Lisää kansioon"</string>
<string name="new_folder" msgid="7743540149088867917">"Uusi kansio"</string>
<string name="edit_folder" msgid="621817453133656156">"Muokkaa kansiota"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Tallenna tietoja verkkolomakkeiden automaattista täyttöä varten"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automaattinen Google-sisäänkirjaus"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Kirjaudutaan Google-sivustoihin käyttäjänimellä <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automaattinen kirjautuminen käytettävissä."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Kirjautunut käyttäjänä"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Kirjaudu"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Piilota"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Kirjautuminen epäonnistui."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Kirjoita tiedot, jotka haluat täyttää automaattisesti verkon kenttiin koskettaessasi kenttiä."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Koko nimi:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Hyvin suuri"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tekstin koko"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Kirjasimen vähimmäiskoko"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Ota skaalaus käyttöön"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Ohitetaanko sivuston pyyntö hallinnoida skaalausta"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Oletuszoomaus"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Kauas"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"korea (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Tekstin koodaus"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Esteettömyys"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Pikasäätimet"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Saat pikasäätimet käyttöösi ja voit piilottaa Sovellus- ja URL-palkit liu\'uttamalla vasemmalta tai oikealta reunalta"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Etusivulla näytetään eniten käyttämäsi verkkosivut."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Käyttämällä Google Instantia hakiessasi näet tuloksia jo hakua kirjoittaessasi (tämä voi kasvattaa tiedonsiirron määrää)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Koko ruutu"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Piilota tilapalkki käyttämällä koko ruudun tilaa."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"UserAgent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Vaihda sivuston tablet- ja pöytäkoneversion välillä"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Vaihda sivuston tablet- ja pöytäkoneversion välillä napauttamalla Android- tai kannettavan tietokoneen kuvaketta."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Datayhteysongelma"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Tiedosto-ongelma"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Vahvista"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Jaa"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Välilehtiä ei ole enempää saatavilla"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google ja Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Palautetaanko ikkunat?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Selain vaikuttaa kaatuneen. Haluatko palauttaa viime kerralla auki olleet ikkunat?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Kyllä"</string>
+ <string name="recover_no" msgid="3121030267940592611">"En"</string>
+ <string name="preview" msgid="1470306351083271066">"Esikatselu:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Paikalliset kirjanmerkit"</string>
</resources>
diff --git a/res/values-fr-sw600dp/strings.xml b/res/values-fr-sw600dp/strings.xml
index 6f36159..6ae1d2b 100644
--- a/res/values-fr-sw600dp/strings.xml
+++ b/res/values-fr-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Ouvrir dans un nouvel onglet d\'arrière-plan"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Toujours ouvrir dans un nouvel onglet"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Ouvrir nouveaux onglets derrière onglet actuel"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Restaurer les onglets ?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Le navigateur semble bloqué. Voulez-vous restaurer les onglets ouverts lors de votre dernière connexion ?"</string>
</resources>
diff --git a/res/values-fr-xlarge/strings.xml b/res/values-fr-xlarge/strings.xml
index 2975ed5..e65274f 100644
--- a/res/values-fr-xlarge/strings.xml
+++ b/res/values-fr-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Ouvrir dans un nouvel onglet d\'arrière-plan"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Toujours ouvrir dans un nouvel onglet"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Ouvrir nouveaux onglets derrière onglet actuel"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Restaurer les onglets ?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Le navigateur semble bloqué. Souhaitez-vous restaurer les onglets ouverts lors de votre dernière connexion ?"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 42219fa..dd4dd00 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Annuler"</string>
<string name="location" msgid="3411848697912600125">"Adresse"</string>
+ <string name="account" msgid="5179824606448077042">"Compte"</string>
<string name="containing_folder" msgid="6771180232953030479">"Ajouter à"</string>
<string name="new_folder" msgid="7743540149088867917">"Nouveau dossier"</string>
<string name="edit_folder" msgid="621817453133656156">"Modifier le dossier"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Saisir et enregistrer des données à des fins de saisie automatique dans les champs de formulaires Web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Connexion automatique à Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Connexion à Google Sites avec le compte <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"La connexion automatique est disponible."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Se connecter à l\'aide du compte"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Connexion"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Masquer"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Échec de la connexion"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Renseignez les données à saisir automatiquement dans les champs Web lorsque vous appuyez sur ces derniers."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nom et prénom :"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Très grande"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Taille de la police"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Taille de police minimale"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Forcer l\'activation du zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Ignorer ou non la demande de contrôle du zoom par un site Web"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom par défaut"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Éloigné"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coréen (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codage du texte"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accessibilité"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Commandes rapides"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Accès commandes rapides/masquer barres applications et URL : faire glisser vers droite/gauche"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Votre page d\'accueil affiche les pages Web les plus visitées."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Recherche instantanée Google"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Affichez plus de résultats lors de la saisie avec la recherche instantanée Google. Peut utiliser plus de données."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Plein écran"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Utiliser le mode plein écran pour masquer la barre d\'état"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"UserAgent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Basculer entre la version pour tablette et la version pour ordinateur d\'un site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Appuyez sur l\'icône Android ou l\'icône représentant un ordinateur portable afin de basculer entre la version pour tablette et la version pour ordinateur d\'un site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problème de connectivité des données"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problème de fichier"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirmer"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Partager"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Plus aucun onglet n\'est disponible."</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google avec Recherche instantanée (Google Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Restaurer les fenêtres ?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Le navigateur semble bloqué. Souhaitez-vous restaurer les fenêtres ouvertes lors de votre dernière connexion ?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Oui"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Non"</string>
+ <string name="preview" msgid="1470306351083271066">"Aperçu :"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Favoris locaux"</string>
</resources>
diff --git a/res/values-hr-sw600dp/strings.xml b/res/values-hr-sw600dp/strings.xml
index 4625edd..7a746d5 100644
--- a/res/values-hr-sw600dp/strings.xml
+++ b/res/values-hr-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Otvori u novoj pozadinskoj kartici"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Otvori sve u novim karticama"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Otvori nove kartice iza trenutačne"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vratiti kartice?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Izgleda da se preglednik srušio. Želite li vratiti kartice od prethodnog puta?"</string>
</resources>
diff --git a/res/values-hr-xlarge/strings.xml b/res/values-hr-xlarge/strings.xml
index e61c130..0b35273 100644
--- a/res/values-hr-xlarge/strings.xml
+++ b/res/values-hr-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Otvori u novoj pozadinskoj kartici"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Otvori sve na novim karticama"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Otvori nove kartice iza trenutne"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vratiti kartice?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Izgleda da je preglednik pao. Želite li vratiti kartice od prethodnog puta?"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index e2636da..bc20138 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"U redu"</string>
<string name="do_not_save" msgid="6777633870113477714">"Odustani"</string>
<string name="location" msgid="3411848697912600125">"Adresa"</string>
+ <string name="account" msgid="5179824606448077042">"Račun"</string>
<string name="containing_folder" msgid="6771180232953030479">"Dodaj u grupu"</string>
<string name="new_folder" msgid="7743540149088867917">"Nova mapa"</string>
<string name="edit_folder" msgid="621817453133656156">"Uredi mapu"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Unošenje i spremanje podataka za automatsko popunjavanje polja web-obrasca"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatska prijava na Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Prijava na Google web-lokacije putem <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Dostupna je automatska prijava."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Prijavite se kao"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Prijava"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Sakrij"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Prijava nije uspjela."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Unesite podatke koje želite automatski unijeti u web-polja kad ih dodirnete."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Puno ime:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Ogroman"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Veličina teksta"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Najmanja veličina fonta"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Prisilno omogući zumiranje"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Poništiti zahtjev web-lokacije za kontrolu ponašanja zumiranja"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zadano povećanje/smanjenje"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Daleko"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"korejski (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Kodiranje teksta"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Dostupnost"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Brze kontrole"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Za pristup brzim kontrolama i skrivanje Aplikacija i URL-ova prijeđite palcem"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Vaša početna stranica prikazuje vaše najposjećenije web-stranice."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Kada u Google Pretraživanju upotrebljavate Google Instant, rezultati se prikazuju dok tipkate (promet podataka može porasti)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Puni zaslon"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Upotrijebite način punog zaslona da biste sakrili traku stanja."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Prebacivač korisničkog agenta"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Prebacivanje između verzija stranice za tabletno i stolno računalo"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Dodirnite ikonu Androida ili prijenosnog računala za prebacivanje između verzije stranice za tabletno i stolno računalo."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problem s podatkovnom povezivošću"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem s datotekom"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Potvrdi"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Dijeli"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Nema više rasp. kartica"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google sa značajkom Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vratiti prozore?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Izgleda da je preglednik pao. Želite li vratiti prozore od prethodnog puta?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Da"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Ne"</string>
+ <string name="preview" msgid="1470306351083271066">"Pregled:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokalno"</string>
</resources>
diff --git a/res/values-hu-sw600dp/strings.xml b/res/values-hu-sw600dp/strings.xml
index 1f0bb2f..3528aa5 100644
--- a/res/values-hu-sw600dp/strings.xml
+++ b/res/values-hu-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Megnyitás új lapon a háttérben"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Összes megnyitása új lapon"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Új lapok megnyitása a jelenlegi mögött"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Visszaállítja a lapokat?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Úgy tűnik, böngészője összeomlott. Szeretné visszaállítani a korábbi lapokat?"</string>
</resources>
diff --git a/res/values-hu-xlarge/strings.xml b/res/values-hu-xlarge/strings.xml
index 76d05c5..0460fbe 100644
--- a/res/values-hu-xlarge/strings.xml
+++ b/res/values-hu-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Megnyitás új lapon a háttérben"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Összes megnyitása új lapon"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Új lapok megnyitása a jelenlegi mögött"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Visszaállítja a lapokat?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Úgy tűnik, hogy böngészője összeomlott. Szeretné visszaállítani a korábbi lapokat?"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 5a5a97e..b971810 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Mégse"</string>
<string name="location" msgid="3411848697912600125">"Cím"</string>
+ <string name="account" msgid="5179824606448077042">"Fiók"</string>
<string name="containing_folder" msgid="6771180232953030479">"Mentés ide:"</string>
<string name="new_folder" msgid="7743540149088867917">"Új mappa"</string>
<string name="edit_folder" msgid="621817453133656156">"Mappa szerkesztése"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Adatok beírása és mentése az internetes űrlapok mezőinek automatikus kitöltéséhez"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatikus Google-bejelentkezés"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Bejelentkezés Google-webhelyekre a következők használatával: <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Az automatikus bejelentkezés elérhető."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Bejelentkezés mint"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Belépés"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Elrejtés"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Sikertelen bejelentkezés."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Adja meg azokat az adatokat, amelyekkel ki szeretné tölteni az internetes mezőket, amikor megérinti azokat."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Teljes név:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Óriási"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Szöveg mérete"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimális betűméret"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Nagyítás engedélyezése"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Webhely kezelheti-e a nagyítást"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Alapértelmezett nagyítás"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Távoli"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Koreai (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Szöveg kódolása"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Kisegítő lehetőségek"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Gyorsbeállítások"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Seperjen az ujjával: gyorsvezérlők elérése, az Alkalmazás és URL-sáv elrejtése."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Kezdőlapján a leggyakrabban felkeresett webhelyek jelennek meg."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"A Google-keresésnél használja a Google Instantot, és a találatok gépelés közben megjelennek (az adatforgalom nőhet)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Teljes képernyő"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Használja a teljes képernyős módot az állapotsor elrejtéséhez."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Felhasználók közötti váltás"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Egy webhely táblagépes és asztali változatai közötti váltás"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Érintse meg az Android vagy a laptop ikont egy webhely táblagépes és asztali változatai közötti váltáshoz."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Adatkapcsolat-probléma"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Probléma van a fájllal"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Megerősítés"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Megosztás"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Nem nyitható meg több lap"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google Instanttal (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Visszaállítja az ablakokat?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Úgy tűnik, hogy böngészője összeomlott. Szeretné visszaállítani a korábbi ablakokat?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Igen"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nem"</string>
+ <string name="preview" msgid="1470306351083271066">"Előnézet:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Helyi"</string>
</resources>
diff --git a/res/values-in-sw600dp/strings.xml b/res/values-in-sw600dp/strings.xml
index 7a3bf2c..86a75e5 100644
--- a/res/values-in-sw600dp/strings.xml
+++ b/res/values-in-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Buka di tab latar belakang baru"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Buka semua di tab baru"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Buka tab baru di belakang tab ini"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Pulihkan tab?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Peramban tampaknya telah mogok. Inginkah Anda memulihkan tab-tab yang terakhir terbuka?"</string>
</resources>
diff --git a/res/values-in-xlarge/strings.xml b/res/values-in-xlarge/strings.xml
index 785a17b..0753ef4 100644
--- a/res/values-in-xlarge/strings.xml
+++ b/res/values-in-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Buka di tab latar belakang baru"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Buka semua di tab baru"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Buka tab baru di belakang tab ini"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Pulihkan tab?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Peramban tampaknya telah mogok. Inginkah Anda memulihkan tab-tab yang terakhir kali terbuka?"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 9e0bd1e..996af38 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Batal"</string>
<string name="location" msgid="3411848697912600125">"Alamat"</string>
+ <string name="account" msgid="5179824606448077042">"Akun"</string>
<string name="containing_folder" msgid="6771180232953030479">"Tambahkan ke"</string>
<string name="new_folder" msgid="7743540149088867917">"Map baru"</string>
<string name="edit_folder" msgid="621817453133656156">"Edit map"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Masukkan dan simpan data untuk mengisi-otomatis bidang formulir web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Masuk ke Google secara otomatis"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Masuk ke situs Google dengan <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Fitur masuk otomatis tersedia."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Masuk sebagai"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Masuk"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Sembunyikan"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Upaya masuk gagal."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Masukkan data yang ingin Anda isi-otomatiskan ke bidang web saat disentuh."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nama lengkap:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Sangat besar"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Ukuran teks"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Ukuran fon minimal"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Paksa aktifkan zum"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Apakah mengesampingkan atau tidak permintaan situs web untuk mengontrol perilaku zum"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom bawaan"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Jauh"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korea (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Penyandiaksaraan teks"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Aksesibilitas"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Kontrol cepat"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Gesek ibu jari dari tepi kiri atau kanan untuk mengakses kontrol cepat dan menyembunyikan bilah aplikasi dan URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Beranda Anda menampilkan situs web yang paling sering disinggahi."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Sekejap"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Gunakan Google Sekejap di Google Penelusuran agar hasilnya tampil selagi mengetik (ini dapat menambah pemakaian data)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Layar penuh"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Gunakan modus layar penuh untuk menyembunyikan bilah status."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Beralih antara situs versi tablet dan desktop"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Ketuk ikon Android atau laptop untuk beralih antara situs versi tablet dan desktop."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Masalah konektivitas data"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Masalah dengan berkas"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Konfirmasi"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Bagikan"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Tidak ada lagi tab yang tersedia"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google dengan Sekejap (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Pulihkan jendela?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Peramban tampaknya telah mogok. Inginkah Anda memulihkan jendela-jendela yang terakhir kali terbuka?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ya"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Tidak"</string>
+ <string name="preview" msgid="1470306351083271066">"Pratinjau:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokal"</string>
</resources>
diff --git a/res/values-it-sw600dp/strings.xml b/res/values-it-sw600dp/strings.xml
index 1774a85..e1886f4 100644
--- a/res/values-it-sw600dp/strings.xml
+++ b/res/values-it-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Apri in una nuova scheda in secondo piano"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Apri tutto in nuove schede"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Apri le nuove schede dietro la scheda corrente"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Ripristinare le schede?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Sembra che si sia verificato un arresto anomalo del browser. Ripristinare le schede che erano aperte durante l\'ultima sessione?"</string>
</resources>
diff --git a/res/values-it-xlarge/strings.xml b/res/values-it-xlarge/strings.xml
index d2dc0e6..e580d2a 100644
--- a/res/values-it-xlarge/strings.xml
+++ b/res/values-it-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Apri in una nuova scheda in secondo piano"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Apri tutto in nuove schede"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Apri le nuove schede dietro la scheda corrente"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Ripristinare le schede?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Sembra che si sia verificato un arresto anomalo del browser. Ripristinare le schede che erano aperte durante l\'ultima sessione?"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 8ac3436..175d976 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Annulla"</string>
<string name="location" msgid="3411848697912600125">"Indirizzo"</string>
+ <string name="account" msgid="5179824606448077042">"Account"</string>
<string name="containing_folder" msgid="6771180232953030479">"Aggiungi a"</string>
<string name="new_folder" msgid="7743540149088867917">"Nuova cartella"</string>
<string name="edit_folder" msgid="621817453133656156">"Modifica cartella"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Inserisci e salva dati per la compilazione automatica dei campi dei moduli web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Accesso Google automatico"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Accesso ai siti Google utilizzando <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Accesso automatico disponibile."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Accesso eseguito come"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Accedi"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Nascondi"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Accesso non riuscito."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Inserisci i dati desiderati per la compilazione automatica dei moduli web quando li tocchi."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nome e cognome:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Molto grande"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Dimensioni testo"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Dimensioni minime caratteri"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Attivazione forzata zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Ignorare o meno la richiesta di un sito di controllare lo zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predefinito"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lontano"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreano (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codifica testo"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accessibilità"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controlli rapidi"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Fai scorrere il pollice dal lato sinistro/destro per accedere ai controlli e nascondere le barre delle applicazioni e dell\'URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"La tua pagina iniziale mostra le tue pagine web più visitate."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Usa Google Instant con Ricerca Google per visualizzare i risultati mentre digiti (può aumentare l\'uso dei dati)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Schermo intero"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Usa la modalità a schermo intero per nascondere la barra di stato."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Selettore user-agent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Spostati tra le versioni tablet e desktop di un sito"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tocca l\'icona Android o del portatile per spostarti tra le versioni tablet e desktop di un sito."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema di connettività dati"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problemi con il file"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Conferma"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Condividi"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Nessun\'altra scheda disponibile"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google con Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Ripristinare le finestre?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Sembra che si sia verificato un arresto anomalo del browser. Ripristinare le finestre che erano aperte durante l\'ultima sessione?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sì"</string>
+ <string name="recover_no" msgid="3121030267940592611">"No"</string>
+ <string name="preview" msgid="1470306351083271066">"Anteprima:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Locali"</string>
</resources>
diff --git a/res/values-iw-sw600dp/strings.xml b/res/values-iw-sw600dp/strings.xml
index 8396347..493fd3d 100644
--- a/res/values-iw-sw600dp/strings.xml
+++ b/res/values-iw-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"פתח בכרטיסיית רקע חדשה"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"פתח הכל בכרטיסיות חדשות"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"פתח כרטיסיות חדשות מאחורי הכרטיסייה הנוכחית"</string>
+ <string name="recover_title" msgid="1558775426269800998">"לשחזר כרטיסיות?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"נראה שהדפדפן קרס. האם ברצונך לשחזר את הכרטיסיות שלך מההפעלה הקודמת?"</string>
</resources>
diff --git a/res/values-iw-xlarge/strings.xml b/res/values-iw-xlarge/strings.xml
index 1ea3357..9660c57 100644
--- a/res/values-iw-xlarge/strings.xml
+++ b/res/values-iw-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"פתח בכרטיסיית רקע חדשה"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"פתח את הכל בכרטיסיות חדשות"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"פתח כרטיסיות חדשות מאחורי הכרטיסייה הנוכחית"</string>
+ <string name="recover_title" msgid="7754049918641251703">"לשחזר כרטיסיות?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"נראה שהדפדפן קרס. האם ברצונך לשחזר את הכרטיסיות שלך מההפעלה הקודמת?"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 0230fc1..bd36055 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"אישור"</string>
<string name="do_not_save" msgid="6777633870113477714">"ביטול"</string>
<string name="location" msgid="3411848697912600125">"כתובת"</string>
+ <string name="account" msgid="5179824606448077042">"חשבון0"</string>
<string name="containing_folder" msgid="6771180232953030479">"הוסף אל"</string>
<string name="new_folder" msgid="7743540149088867917">"תיקיה חדשה"</string>
<string name="edit_folder" msgid="621817453133656156">"ערוך תיקיה"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"הזן נתונים ושמור אותם למילוי אוטומטי של שדות בטופס אינטרנט"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"כניסה אוטומטית ל-Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"כניסה אל Google Sites באמצעות <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"הכניסה האוטומטית זמינה."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"היכנס כ:"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"התחבר"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"הסתר"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"ההתחברות נכשלה."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"הזן את הנתונים שברצונך למלא באופן אוטומטי בשדות באינטרנט כאשר תיגע בשדות אלה."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"שם מלא:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"ענק"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"גודל טקסט"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"גודל גופן מינימלי"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"אלץ הפעלת מרחק מתצוגה"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"האם לעקוף או לא לעקוף בקשה של אתר כדי לשלוט באופן הפעולה של מרחק מתצוגה"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"ברירת מחדל של מרחק מתצוגה"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"רחוק"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"קוריאנית (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"קידוד טקסט"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"נגישות"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"פקדים מהירים"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"העבר את האגודל מאחד הצדדים כדי לגשת לפקדים המהירים ולהסתיר את סרגלי היישום וה-URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"דף הבית שלך מציג את דפי האינטרנט שבהם ביקרת בתדירות הגבוהה ביותר."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"השתמש ב-Google Instant כאשר אתה משתמש בחיפוש Google, כדי להציג תוצאות בעת ההקלדה (פעולה זו יכולה להגדיל שימוש בנתונים)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"מסך מלא"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"השתמש במצב מסך מלא כדי להסתיר את שורת המצב."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"מחליף סוכן משתמש"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"מעבר בין גרסת טבלט לגרסת שולחן העבודה של אתר"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"הקש על הסמל Android או על הסמל \'מחשב נייד\' כדי לעבור בין גרסה לטבלט לגרסה לשולחן עבודה של אתר."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"בעיה בקישוריות נתונים"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"בעיה בקובץ"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"אשר"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"שתף"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"אין עוד כרטיסיות זמינות"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google עם Instant (Google Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"לשחזר חלונות?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"נראה שהדפדפן קרס. האם ברצונך לשחזר את החלונות שלך מההפעלה הקודמת?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"כן"</string>
+ <string name="recover_no" msgid="3121030267940592611">"לא"</string>
+ <string name="preview" msgid="1470306351083271066">"תצוגה מקדימה:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"מקומי"</string>
</resources>
diff --git a/res/values-ja-sw600dp/strings.xml b/res/values-ja-sw600dp/strings.xml
index 31c13a1..de56272 100644
--- a/res/values-ja-sw600dp/strings.xml
+++ b/res/values-ja-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"新しいバックグラウンドタブで開く"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"すべて新しいタブで開く"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"現在のタブの後ろに新しいタブを開く"</string>
+ <string name="recover_title" msgid="1558775426269800998">"タブを復元しますか?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"ブラウザはクラッシュしたようです。前回のタブを復元しますか?"</string>
</resources>
diff --git a/res/values-ja-xlarge/strings.xml b/res/values-ja-xlarge/strings.xml
index 7e75d86..d3681f3 100644
--- a/res/values-ja-xlarge/strings.xml
+++ b/res/values-ja-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"新しいバックグラウンドタブで開く"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"常に新しいタブで開く"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"現在のタブの後ろに新しいタブを開く"</string>
+ <string name="recover_title" msgid="7754049918641251703">"タブを復元しますか?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"ブラウザはクラッシュしたようです。前回のタブを復元しますか?"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 3a4c996..835e57f 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"キャンセル"</string>
<string name="location" msgid="3411848697912600125">"アドレス"</string>
+ <string name="account" msgid="5179824606448077042">"アカウント"</string>
<string name="containing_folder" msgid="6771180232953030479">"追加先"</string>
<string name="new_folder" msgid="7743540149088867917">"新しいフォルダ"</string>
<string name="edit_folder" msgid="621817453133656156">"フォルダを編集"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"ウェブフォームフィールドに自動入力するデータを入力、保存する"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Googleへの自動ログイン"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"<xliff:g id="ID_1">%s</xliff:g>を使用してGoogleサイトにログインしています"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"自動ログインを利用できます。"</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"次のアカウントでログイン"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"ログイン"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"表示しない"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"ログインに失敗しました。"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"ウェブ上でフィールドをタップしたときに自動入力するデータを入力します。"</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"氏名:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"最大"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"文字サイズ"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"最小フォントサイズ"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"拡大縮小設定の上書き"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"サイトの拡大縮小設定を上書き"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"デフォルトの倍率"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"低"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"韓国語(EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"テキストエンコード"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"ユーザー補助"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"クイックコントロール"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"クイックコントロールへのアクセス(アプリ/URLバー非表示)には左/右端からスワイプ"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"アクセス数が最も多いウェブページをホームページとして表示します。"</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Googleインスタント検索"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Google検索時にGoogleインスタント検索を使用すると、入力中に結果が表示されます(データの使用量が増えることがあります)。"</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"全画面"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"全画面モードを使用してステータスバーを非表示にする。"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"ユーザーエージェント切り替え機能"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"サイトのタブレット版とデスクトップ版を切り替える"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"サイトのタブレット版とデスクトップ版を切り替えるには、Androidアイコンまたはノートパソコンのアイコンをタップします。"</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"データアクセスエラー"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"ファイルに問題があります"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"確認"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"共有"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"タブ数が上限に達しました"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Googleインスタント検索(Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"ウィンドウを復元しますか?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"ブラウザはクラッシュしたようです。前回のウィンドウを復元しますか?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"はい"</string>
+ <string name="recover_no" msgid="3121030267940592611">"いいえ"</string>
+ <string name="preview" msgid="1470306351083271066">"プレビュー:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"ローカル"</string>
</resources>
diff --git a/res/values-ko-sw600dp/strings.xml b/res/values-ko-sw600dp/strings.xml
index 4da5e73..8454eee 100644
--- a/res/values-ko-sw600dp/strings.xml
+++ b/res/values-ko-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"새 배경 탭에서 열기"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"새 탭에서 모두 열기"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"현재 탭 뒤에 새 탭 열기"</string>
+ <string name="recover_title" msgid="1558775426269800998">"탭을 복원하시겠습니까?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"브라우저가 멈춘 것 같습니다. 마지막에 열려있던 탭을 복원하시겠습니까?"</string>
</resources>
diff --git a/res/values-ko-xlarge/strings.xml b/res/values-ko-xlarge/strings.xml
index 63bd6a1..c2e21ce 100644
--- a/res/values-ko-xlarge/strings.xml
+++ b/res/values-ko-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"새 배경 탭에서 열기"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"새 탭에서 모두 열기"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"현재 탭 뒤에 새 탭 열기"</string>
+ <string name="recover_title" msgid="7754049918641251703">"탭을 복원하시겠습니까?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"브라우저가 멈추었습니다. 마지막에 열려있던 탭을 복원하시겠습니까?"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index ccc1d38..9ef38b2 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"확인"</string>
<string name="do_not_save" msgid="6777633870113477714">"취소"</string>
<string name="location" msgid="3411848697912600125">"주소"</string>
+ <string name="account" msgid="5179824606448077042">"계정"</string>
<string name="containing_folder" msgid="6771180232953030479">"추가할 위치"</string>
<string name="new_folder" msgid="7743540149088867917">"새 폴더"</string>
<string name="edit_folder" msgid="621817453133656156">"폴더 수정"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"자동 입력 웹 양식 필드에 대한 데이터 입력 및 저장"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"자동 Google 로그인"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"<xliff:g id="ID_1">%s</xliff:g>(으)로 Google 사이트에 로그인 중"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"자동 로그인을 사용할 수 있습니다."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"다음 사용자로 로그인:"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"로그인"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"숨기기"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"로그인하지 못했습니다."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"터치할 때 웹 입력란에 자동 완성되도록 하려는 데이터를 입력하세요."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"이름:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"아주 크게"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"텍스트 크기"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"최소 글꼴 크기"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"확대/축소 강제 사용"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"확대/축소 요청 무시 여부"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"기본 확대/축소"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"축소"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"한국어(EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"텍스트 인코딩"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"접근성"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"실험실"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"빠른 컨트롤"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"좌/우 끝에서 엄지로 스와이프하여 빠른 컨트롤에 액세스하고 앱 및 URL 표시줄 숨김"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"홈페이지에 자주 방문한 웹페이지가 표시됩니다."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google 순간 검색"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Google 검색을 사용할 때 Google 순간 검색을 사용하면 입력하는 동안 결과가 표시됩니다(데이터 사용이 증가될 수 있음)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"전체화면"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"전체화면 모드를 사용하여 상태 표시줄을 숨깁니다."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"사용자 에이전트 전환"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"사이트의 태블릿 버전과 데스크톱 버전 사이를 전환합니다."</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"사이트의 태블릿 버전과 데스크톱 버전 사이를 전환하려면 Android 또는 노트북 아이콘을 누르세요."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"데이터 연결에 문제 발생"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"파일 문제 발생"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"확인"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"공유"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"탭이 더 이상 없습니다."</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google 순간 검색(실험실)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"창을 복원하시겠습니까?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"브라우저가 멈추었습니다. 마지막에 열려있던 창을 복원하시겠습니까?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"예"</string>
+ <string name="recover_no" msgid="3121030267940592611">"아니요"</string>
+ <string name="preview" msgid="1470306351083271066">"미리보기:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"로컬"</string>
</resources>
diff --git a/res/values-land/dimensions.xml b/res/values-land/dimensions.xml
index f3b1235..df4bc84 100644
--- a/res/values-land/dimensions.xml
+++ b/res/values-land/dimensions.xml
@@ -15,4 +15,6 @@
<dimen name="preference_screen_side_margin">96dp</dimen>
<dimen name="preference_screen_side_margin_negative">-100dp</dimen>
<dimen name="preference_widget_width">72dp</dimen>
+ <dimen name="nav_tab_width">280dip</dimen>
+ <dimen name="nav_tab_height">240dip</dimen>
</resources>
diff --git a/res/values-lt-sw600dp/strings.xml b/res/values-lt-sw600dp/strings.xml
index 100acd1..4735874 100644
--- a/res/values-lt-sw600dp/strings.xml
+++ b/res/values-lt-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Atidaryti naujame fono skirtuke"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Atidaryti visas naujuose skirtukuose"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Atidaryti naujus skirtukus už dabartinio"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Atkurti skirtukus?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Atrodo, kad naršyklė užstrigo. Ar norėtumėte atkurti paskutinį kartą naudotus skirtukus?"</string>
</resources>
diff --git a/res/values-lt-xlarge/strings.xml b/res/values-lt-xlarge/strings.xml
index 7fedc78..832e6ff 100644
--- a/res/values-lt-xlarge/strings.xml
+++ b/res/values-lt-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Atidaryti naujame fono skirtuko lape"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Atidaryti visas naujuose skirtukų lapuose"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Atidaroma naujų skirtukų lapų už dabartinio"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Atkurti skirtukus?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Atrodo, naršyklė užstrigo. Ar norėtumėte atkurti paskutinį kartą naudotus skirtukus?"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index f449b26..91e22dc 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Gerai"</string>
<string name="do_not_save" msgid="6777633870113477714">"Atšaukti"</string>
<string name="location" msgid="3411848697912600125">"Adresas"</string>
+ <string name="account" msgid="5179824606448077042">"Paskyra"</string>
<string name="containing_folder" msgid="6771180232953030479">"Pridėti prie"</string>
<string name="new_folder" msgid="7743540149088867917">"Naujas aplankas"</string>
<string name="edit_folder" msgid="621817453133656156">"Redaguoti aplanką"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Įveskite duomenis ir išsaugokite juos automatinio pildymo formos žiniatinklyje laukuose"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Autom. prisijung. prie „Google“"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Prisijungiama prie „Google“ svetainių naudojant <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Galimas automatinis prisijungimas."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Prisijungti kaip"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Prisijung."</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Slėpti"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Nepavyko prisijungti."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Įveskite duomenis, kuriais norite automatiškai užpildyti žiniatinklio laukus, kai juos paliesite."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Vardas ir pavardė:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Didžiulis"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Teksto dydis"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Mažiausias šrifto dydis"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Priverstinai įgal. mast. keit."</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Ar įr. svet. užkl. vald. mast. keit. elgs."</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Numatytasis mastelio keitimas"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Toli"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korėjiečių (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Teksto koduotė"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Pasiekiamumas"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laboratorijos"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Spartieji valdikliai"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Sl. nykščiu iš kair. ar deš. kr., kad pasiekt. sparč. vald. ir pasl. pr. ir URL juost."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Pagrindiniame puslapyje pateikiami dažniausiai lankyti tinklalapiai."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Intuityvioji „Google“ paieška"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Kai naud. „Google“ paiešką, naud. Int. „Google“ paiešką, kad renk. tekst. b. rodomi rezult. (tai g. padid. duom. naud.)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Visas ekranas"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Jei norite paslėpti būsenos juostą, naudokite viso ekrano režimą."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Naudotojo priemonės perjungiklis"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Perjunkite iš planšetiniam kompiuteriui skirtos svetainės versijos į skirtą staliniam (ir atvirkščiai)"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Jei norite perjungti iš planšetiniam kompiuteriui skirtos svetainės versijos į skirtą staliniam (ir atvirkščiai), palieskite „Android“ arba nešiojamojo kompiuterio piktogramą."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Duomenų jungiamumo problema"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Failo problema"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Patvirtinti"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Bendrinti"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Daugiau galimų skirtukų nėra"</string>
<string name="instant_search_label" msgid="8769284297650716935">"„Google“ su Intuityviąja paieška (Laboratorijos)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Atkurti langus?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Atrodo, naršyklė užstrigo. Ar norėtumėte atkurti paskutinį kartą naudotus langus?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Taip"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Ne"</string>
+ <string name="preview" msgid="1470306351083271066">"Peržiūra:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Vietinės"</string>
</resources>
diff --git a/res/values-lv-sw600dp/strings.xml b/res/values-lv-sw600dp/strings.xml
index ba2eb73..ea471c5 100644
--- a/res/values-lv-sw600dp/strings.xml
+++ b/res/values-lv-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Atvērt jaunā fona cilnē"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Atvērt visas grāmatzīmes jaunās cilnēs"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Atvērt jaunas cilnes aiz pašreiz atvērtās"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vai atjaunot cilnes?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Notika pārlūkprogrammas avārija. Vai vēlaties atjaunot pēdējās atvērtās cilnes?"</string>
</resources>
diff --git a/res/values-lv-xlarge/strings.xml b/res/values-lv-xlarge/strings.xml
index 75c6059..0279ba9 100644
--- a/res/values-lv-xlarge/strings.xml
+++ b/res/values-lv-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Atvērt jaunā fona cilnē"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Atvērt visas jaunās cilnēs"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Atvērt jaunas cilnes aiz pašreizējās"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vai atjaunot cilnes?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Notika pārlūkprogrammas avārija. Vai vēlaties atjaunot pēdējās atvērtās cilnes?"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7322e2e..3f6fbea 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Labi"</string>
<string name="do_not_save" msgid="6777633870113477714">"Atcelt"</string>
<string name="location" msgid="3411848697912600125">"Adrese"</string>
+ <string name="account" msgid="5179824606448077042">"Konts"</string>
<string name="containing_folder" msgid="6771180232953030479">"Pievienot:"</string>
<string name="new_folder" msgid="7743540149088867917">"Jauna mape"</string>
<string name="edit_folder" msgid="621817453133656156">"Rediģēt mapi"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Ievadiet un saglabājiet datus tīmekļa veidlapu lauku automātiskai aizpildīšanai."</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Autom. pierakst. vietnē Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Pierakstīšanās pakalpojumā Google vietnes, izmantojot <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Ir pieejama automātiskā pierakstīšanās."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Pierakstīties kā"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Pieteikties"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Paslēpt"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Neizdevās pieteikties."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Ievadiet datus, kas automātiski jāaizpilda tīmekļa laukos, kad tiem pieskaraties."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Vārds, uzvārds:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Milzīgs"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Teksta lielums"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimālais fonta lielums"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Pieprasīt tālummaiņas iespēj."</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Ignorēt vietnes piepr. par tālummaiņas kontrolēšanu vai ne."</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Noklusējuma tālummaiņa"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Tālu"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korejiešu (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Teksta kodējums"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Pieejamība"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laboratorijas"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Ātrās piekļuves vadīklas"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Lai piekļ. ātr. piekļ. vadīklām un slēptu lietojumpr. un URL joslas, ekr. lab. vai kr. malā pavelciet ar īkšķi."</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Sākumlapā tiek rādītas biežāk apmeklētās tīmekļa lapas."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google dinamiskā meklēšana"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Izmantojiet Google dinamisko meklēšanu, kad lietojat Google meklēšanu, lai redzētu rezultātus rakstīšanas laikā (var tikt izmantots vairāk datu)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Pilnekrāna režīms"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Lai paslēptu statusa joslu, izmantojiet pilnekrāna režīmu."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Lietotāja aģenta pārslēdzējs"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Vietnes planšetdatora un galddatora versijas pārslēgšana"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Pieskarieties Android vai klēpjdatora ikonai, lai pārslēgtu vietnes planšetdatora un galddatora versiju."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Datu savienojamības problēma"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Faila problēma"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Apstiprināt"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Kopīgot"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Vairs nav pieejamu ciļņu"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Pakalpojums Google ar dinamisko meklēšanu (Laboratorijas)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vai atjaunot logus?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Notika pārlūkprogrammas avārija. Vai vēlaties atjaunot pēdējos atvērtos logus?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Jā"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nē"</string>
+ <string name="preview" msgid="1470306351083271066">"Priekšskatījums:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Vietējās"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
new file mode 100644
index 0000000..75ad126
--- /dev/null
+++ b/res/values-ms/strings.xml
@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 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" msgid="1935869255545976415">"Penyemak imbas"</string>
+ <!-- no translation found for choose_upload (3649366287575002063) -->
+ <skip />
+ <!-- no translation found for uploads_disabled (463761197575372994) -->
+ <skip />
+ <!-- no translation found for new_tab (4505722538297295141) -->
+ <skip />
+ <!-- no translation found for new_incognito_tab (5821404839654751753) -->
+ <skip />
+ <!-- no translation found for active_tabs (3050623868203544623) -->
+ <skip />
+ <string name="tab_bookmarks" msgid="2305793036003473653">"Penanda halaman"</string>
+ <string name="tab_most_visited" msgid="1077402532455000703">"Yang paling kerap dilawati"</string>
+ <string name="tab_history" msgid="1979267558744613746">"Sejarah"</string>
+ <string name="added_to_bookmarks" msgid="1020224130695956728">"Ditambah ke penanda halaman"</string>
+ <string name="removed_from_bookmarks" msgid="6063705902028438800">"Dialih keluar daripada penanda halaman"</string>
+ <string name="sign_in_to" msgid="5939425800148759165">"Log masuk ke \"<xliff:g id="REALM">%s2</xliff:g>\" <xliff:g id="HOSTNAME">%s1</xliff:g>"</string>
+ <string name="username" msgid="5057566336518215922">"Nama"</string>
+ <string name="password" msgid="1177138552305184404">"Kata laluan"</string>
+ <string name="action" msgid="183105774472071343">"Log masuk"</string>
+ <string name="bookmarks_search" msgid="5229596268214362873">"Penyemak imbas"</string>
+ <string name="cancel" msgid="3017274947407233702">"Batal"</string>
+ <string name="ok" msgid="1509280796718850364">"OK"</string>
+ <!-- no translation found for title_bar_loading (7438217780834640678) -->
+ <skip />
+ <string name="page_info" msgid="4048529256302257195">"Maklumat halaman"</string>
+ <string name="page_info_view" msgid="5303490449842635158">"Lihat maklumat halaman"</string>
+ <string name="page_info_address" msgid="2222306609532903254">"Alamat:"</string>
+ <string name="ssl_warnings_header" msgid="79744901983636370">"Terdapat masalah dengan sijil keselamatan untuk tapak ini."</string>
+ <string name="ssl_continue" msgid="8031515015829358457">"Teruskan"</string>
+ <string name="security_warning" msgid="6607795404322797541">"Amaran keselamatan"</string>
+ <string name="view_certificate" msgid="1472768887529093862">"Lihat sijil"</string>
+ <!-- no translation found for ssl_go_back (4598951822061593819) -->
+ <skip />
+ <string name="ssl_untrusted" msgid="5369967226521102194">"Sijil ini bukan daripada pihak berkuasa yang dipercayai."</string>
+ <string name="ssl_mismatch" msgid="558688832420069896">"Nama tapak tidak sepadan dengan nama pada sijil."</string>
+ <string name="ssl_expired" msgid="5739349389499575559">"Sijil ini telah tamat tempoh."</string>
+ <string name="ssl_not_yet_valid" msgid="2893167846212645846">"Sijil ini belum lagi sah."</string>
+ <string name="ssl_certificate" msgid="5226747157992111668">"Sijil keselamatan"</string>
+ <string name="ssl_certificate_is_valid" msgid="7096160815933145579">"Sijil ini sah."</string>
+ <string name="issued_to" msgid="9032338008819841339">"Dikeluarkan kepada:"</string>
+ <string name="common_name" msgid="5745530093500062357">"Nama biasa:"</string>
+ <string name="org_name" msgid="8868889052889991293">"Organisasi:"</string>
+ <string name="org_unit" msgid="4489056376307768196">"Unit Organisasi:"</string>
+ <string name="issued_by" msgid="6959484326943152487">"Dikeluarkan oleh:"</string>
+ <string name="validity_period" msgid="57988851973181309">"Kesahan:"</string>
+ <string name="issued_on" msgid="2082890654801808368">"Dikeluarkan pada:"</string>
+ <string name="expires_on" msgid="8061200430557020704">"Tamat tempoh pada:"</string>
+ <string name="stopping" msgid="4839698519340302982">"Menghentikan…"</string>
+ <string name="stop" msgid="5687251076030630074">"Henti"</string>
+ <string name="reload" msgid="8585220783228408062">"Muat semula"</string>
+ <string name="back" msgid="8414603107175713668">"Kembali"</string>
+ <string name="forward" msgid="4288210890526641577">"Ke hadapan"</string>
+ <string name="save" msgid="5922311934992468496">"OK"</string>
+ <string name="do_not_save" msgid="6777633870113477714">"Batal"</string>
+ <!-- outdated translation 969988560160364559 --> <string name="location" msgid="3411848697912600125">"Lokasi"</string>
+ <!-- no translation found for account (5179824606448077042) -->
+ <skip />
+ <!-- no translation found for containing_folder (6771180232953030479) -->
+ <skip />
+ <!-- no translation found for new_folder (7743540149088867917) -->
+ <skip />
+ <!-- no translation found for edit_folder (621817453133656156) -->
+ <skip />
+ <!-- no translation found for delete_folder (2046483129024501116) -->
+ <skip />
+ <!-- no translation found for no_subfolders (5880411440592452802) -->
+ <skip />
+ <!-- no translation found for add_to_bookmarks_menu_option (4449323955122214389) -->
+ <skip />
+ <!-- no translation found for add_to_homescreen_menu_option (1461447829242963790) -->
+ <skip />
+ <!-- no translation found for add_to_other_folder_menu_option (5450890093372998187) -->
+ <skip />
+ <!-- outdated translation 5990326151488445481 --> <string name="name" msgid="5462672162695365387">"Nama"</string>
+ <string name="http" msgid="2163722670597250102">"http://"</string>
+ <!-- no translation found for save_to_bookmarks (6101482434920313244) -->
+ <skip />
+ <!-- no translation found for bookmark_this_page (7530739804320811054) -->
+ <skip />
+ <string name="remove" msgid="7820112494467011374">"Alih keluar"</string>
+ <string name="edit_bookmark" msgid="5024089053490231905">"Edit penanda halaman"</string>
+ <!-- outdated translation 9202323987633899835 --> <string name="create_shortcut_bookmark" msgid="1995095662095484289">"Tambah pintasan ke Laman Utama"</string>
+ <string name="open_bookmark" msgid="8473581305759935790">"Buka"</string>
+ <string name="remove_bookmark" msgid="8407495852801410891">"Padam penanda halaman"</string>
+ <!-- no translation found for remove_from_bookmarks (4374080666576982775) -->
+ <skip />
+ <string name="remove_history_item" msgid="5021424935726728618">"Alih keluar daripada sejarah"</string>
+ <!-- no translation found for set_as_homepage (4752937379414905560) -->
+ <skip />
+ <string name="bookmark_saved" msgid="2766434679871317557">"Disimpan ke penanda halaman."</string>
+ <!-- no translation found for bookmark_not_saved (700600955089376724) -->
+ <skip />
+ <!-- no translation found for homepage_set (8768087280310966395) -->
+ <skip />
+ <string name="bookmark_needs_title" msgid="6245900436119218187">"Penanda halaman mesti mempunyai nama."</string>
+ <string name="bookmark_needs_url" msgid="7809876865972755158">"Penanda halaman mesti mempunyai lokasi."</string>
+ <string name="bookmark_url_not_valid" msgid="6719785633980202419">"URL tidak sah."</string>
+ <!-- no translation found for bookmark_cannot_save_url (791722768778386941) -->
+ <skip />
+ <string name="delete_bookmark" msgid="2422989994934201992">"Padam"</string>
+ <string name="bookmark_page" msgid="6845189305130307274">"Tandakan halaman yang terakhir dilihat"</string>
+ <!-- no translation found for bookmark_thumbnail_view (3164068314718522138) -->
+ <skip />
+ <!-- no translation found for bookmark_list_view (7848510619500937839) -->
+ <skip />
+ <string name="current_page" msgid="7510129573681663135">"dari "</string>
+ <string name="delete_bookmark_warning" msgid="758043186202032205">"Penanda halaman \"<xliff:g id="BOOKMARK">%s</xliff:g>\" akan dipadamkan."</string>
+ <!-- no translation found for open_all_in_new_window (6514602245828366045) -->
+ <skip />
+ <string name="goto_dot" msgid="3895839050522602723">"Pergi"</string>
+ <!-- no translation found for incognito_tab (5419458065370134289) -->
+ <skip />
+ <string name="select_dot" msgid="6299170761900561967">"Pilih teks"</string>
+ <string name="tab_picker_title" msgid="864478399057782913">"Tetingkap semasa"</string>
+ <string name="tab_picker_remove_tab" msgid="630087809802479397">"Tutup"</string>
+ <string name="bookmarks" msgid="1961279134885867815">"Penanda halaman"</string>
+ <string name="shortcut_bookmark" msgid="3974876480401135895">"Penanda halaman"</string>
+ <string name="history" msgid="2451240511251410032">"Sejarah"</string>
+ <string name="menu_view_download" msgid="2124570321712995120">"Muat turun"</string>
+ <!-- no translation found for copy_page_url (7635062169011319208) -->
+ <skip />
+ <string name="share_page" msgid="593756995297268343">"Kongsi halaman"</string>
+ <!-- no translation found for menu_save_webarchive (2474117375302625691) -->
+ <skip />
+ <!-- no translation found for webarchive_saved (2212053339474523406) -->
+ <skip />
+ <!-- no translation found for webarchive_failed (19950914584285713) -->
+ <skip />
+ <!-- no translation found for contextheader_folder_bookmarkcount (353987136645619089) -->
+ <skip />
+ <!-- no translation found for contextheader_folder_empty (974171637803391651) -->
+ <skip />
+ <string name="contextmenu_openlink" msgid="7237961252214188935">"Buka"</string>
+ <string name="contextmenu_openlink_newwindow" msgid="992765050093960353">"Buka dalam tetingkap baru"</string>
+ <!-- no translation found for contextmenu_openlink_newwindow_background (5556131402560251639) -->
+ <skip />
+ <string name="contextmenu_savelink" msgid="5508554930832538184">"Simpan pautan"</string>
+ <string name="contextmenu_sharelink" msgid="5392275392280130331">"Kongsi pautan"</string>
+ <string name="contextmenu_copy" msgid="398860586635404030">"Salin"</string>
+ <string name="contextmenu_copylink" msgid="5153657160294534270">"Salin URL pautan"</string>
+ <string name="contextmenu_download_image" msgid="4243829645180686912">"Simpan imej"</string>
+ <string name="contextmenu_view_image" msgid="3870625602053600905">"Papar imej"</string>
+ <!-- no translation found for contextmenu_set_wallpaper (3691902960115350686) -->
+ <skip />
+ <string name="contextmenu_dial_dot" msgid="5856550683415933806">"Dail..."</string>
+ <string name="contextmenu_add_contact" msgid="3183511922223645716">"Tambah kenalan"</string>
+ <string name="contextmenu_send_mail" msgid="1014513374828775660">"Hantar e-mel"</string>
+ <string name="contextmenu_map" msgid="7471390435434034912">"Peta"</string>
+ <!-- no translation found for choosertitle_sharevia (4600490613341909086) -->
+ <skip />
+ <string name="clear" msgid="7070043081700011461">"Padam bersih"</string>
+ <string name="replace" msgid="4843033491070384047">"Gantikan"</string>
+ <string name="browser_bookmarks_page_bookmarks_text" msgid="6787605028726162673">"Penanda halaman"</string>
+ <string name="menu_preferences" msgid="6709237687234102240">"Tetapan"</string>
+ <string name="pref_content_title" msgid="722227111894838633">"Tetapan kandungan halaman"</string>
+ <string name="pref_content_load_images" msgid="2125616852957377561">"Muatkan imej"</string>
+ <!-- no translation found for pref_content_load_images_summary (5055874125248398584) -->
+ <skip />
+ <!-- outdated translation 7808433807197256726 --> <string name="pref_content_block_popups" msgid="4158524847764470895">"Sekat tetingkap pop-up"</string>
+ <string name="pref_content_javascript" msgid="4570972030299516843">"Dayakan JavaScript"</string>
+ <string name="pref_content_open_in_background" msgid="824123779725118663">"Buka di latar belakang"</string>
+ <!-- no translation found for pref_content_plugins (7231944644794301582) -->
+ <skip />
+ <!-- no translation found for pref_content_plugins_choices:0 (6745108155096660725) -->
+ <!-- no translation found for pref_content_plugins_choices:1 (2484126708670016519) -->
+ <!-- no translation found for pref_content_plugins_choices:2 (8547442717307793863) -->
+ <!-- no translation found for pref_content_open_in_background_summary (1737664075721181678) -->
+ <skip />
+ <!-- outdated translation 6082437160778559806 --> <string name="pref_content_homepage" msgid="3324574611613105696">"Tetapkan laman utama"</string>
+ <!-- no translation found for pref_content_search_engine (1620101310821644144) -->
+ <skip />
+ <!-- no translation found for pref_content_search_engine_summary (5162667665858487316) -->
+ <skip />
+ <!-- no translation found for pref_set_homepage_to (7196350233061395098) -->
+ <skip />
+ <!-- no translation found for pref_use_current (1778622474040406672) -->
+ <skip />
+ <!-- no translation found for pref_use_blank (8503238592551111169) -->
+ <skip />
+ <!-- no translation found for pref_use_default (192587563274735878) -->
+ <skip />
+ <string name="pref_content_autofit" msgid="8260474534053660809">"Muat auto halaman"</string>
+ <!-- no translation found for pref_content_autofit_summary (4587831659894879986) -->
+ <skip />
+ <!-- no translation found for pref_general_title (1946872771219249323) -->
+ <skip />
+ <!-- no translation found for pref_general_sync_title (3138637035975860324) -->
+ <skip />
+ <!-- no translation found for pref_general_autofill_title (547881256865816858) -->
+ <skip />
+ <!-- no translation found for pref_personal_sync_with_chrome (1695182180332194033) -->
+ <skip />
+ <!-- no translation found for pref_personal_sync_with_chrome_summary (7414133931827321055) -->
+ <skip />
+ <!-- no translation found for pref_personal_google_account (952360133341490071) -->
+ <skip />
+ <!-- no translation found for pref_personal_sync_bookmarks (59237515966184432) -->
+ <skip />
+ <!-- no translation found for pref_personal_sync_bookmarks_summary (4791767605662205482) -->
+ <skip />
+ <!-- no translation found for pref_personal_start_syncing (6046972042512655232) -->
+ <skip />
+ <!-- no translation found for pref_personal_account_dialog_title (1390867119887955530) -->
+ <skip />
+ <!-- no translation found for pref_autofill_enabled (1015751713312396713) -->
+ <skip />
+ <!-- no translation found for pref_autofill_enabled_summary (422640696197018914) -->
+ <skip />
+ <!-- no translation found for pref_autofill_profile_editor (3864116896052437796) -->
+ <skip />
+ <!-- no translation found for pref_autofill_profile_editor_summary (3653552312512743181) -->
+ <skip />
+ <!-- no translation found for pref_autologin_title (2362827272595366379) -->
+ <skip />
+ <!-- no translation found for pref_autologin_progress (8333244467048833461) -->
+ <skip />
+ <!-- no translation found for autologin_bar_text (3684581827167173371) -->
+ <skip />
+ <!-- no translation found for autologin_bar_login_text (7052816600314556734) -->
+ <skip />
+ <!-- no translation found for autologin_bar_hide_text (3629355974385859580) -->
+ <skip />
+ <!-- no translation found for autologin_bar_error (5132514366023044839) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_heading (8392952553626722083) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_name (8566130291459685955) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_email_address (7967585896612797173) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_company_name (2813443159949210417) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1 (836433242509243081) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1_hint (5965659598509327172) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2 (8194745202893822479) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2_hint (2048330295853546405) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_city (4193225955409148508) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_state (8549739922338171458) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_zip_code (283668573295656671) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_country (7234470301239156656) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number (4938852821413729276) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number_invalid (7166394872369167580) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_save_profile (8349915287435262888) -->
+ <skip />
+ <!-- no translation found for autofill_profile_successful_save (6834102203944938409) -->
+ <skip />
+ <!-- no translation found for autofill_profile_successful_delete (2421442112954362732) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_delete_profile (2754563301088418752) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_message (6605682320156223114) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_negative_toast (6990737008936188620) -->
+ <skip />
+ <!-- no translation found for disable_autofill (8305901059849400354) -->
+ <skip />
+ <!-- no translation found for pref_privacy_security_title (3480313968942160914) -->
+ <skip />
+ <string name="pref_privacy_clear_cache" msgid="3380316479925886998">"Padam bersih cache"</string>
+ <!-- no translation found for pref_privacy_clear_cache_summary (2216463577207991454) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cache_dlg (5541011591300753881) -->
+ <skip />
+ <!-- no translation found for pref_privacy_cookies_title (6763274282214830526) -->
+ <skip />
+ <string name="pref_privacy_clear_cookies" msgid="3095583579133780331">"Padam bersih semua data kuki"</string>
+ <!-- no translation found for pref_privacy_clear_cookies_summary (6962742063990677520) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cookies_dlg (552855688091432682) -->
+ <skip />
+ <string name="pref_privacy_clear_history" msgid="8723795508825198477">"Padam bersih sejarah"</string>
+ <string name="pref_privacy_clear_history_summary" msgid="6868501330708940734">"Padam bersih sejarah navigasi penyemak imbas"</string>
+ <!-- no translation found for pref_privacy_clear_history_dlg (544903007914753853) -->
+ <skip />
+ <!-- no translation found for pref_privacy_formdata_title (6549813837982050424) -->
+ <skip />
+ <string name="pref_privacy_clear_form_data" msgid="4232668196344383987">"Padam bersih data borang"</string>
+ <string name="pref_privacy_clear_form_data_summary" msgid="1790390894719517167">"Padam bersih semua data borang yang disimpan"</string>
+ <!-- no translation found for pref_privacy_clear_form_data_dlg (4443621086781197928) -->
+ <skip />
+ <string name="pref_privacy_clear_passwords" msgid="4750234112289277480">"Padam bersih kata laluan"</string>
+ <!-- no translation found for pref_privacy_clear_passwords_summary (8856782718942903335) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_passwords_dlg (2083869328824248255) -->
+ <skip />
+ <!-- no translation found for pref_privacy_location_title (7458378016606081067) -->
+ <skip />
+ <!-- no translation found for pref_privacy_enable_geolocation (1395040170290765686) -->
+ <skip />
+ <!-- no translation found for pref_privacy_enable_geolocation_summary (8437020934664306205) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_geolocation_access (6649680770030042980) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_geolocation_access_summary (7750143359497314679) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_geolocation_access_dlg (7327063124488827244) -->
+ <skip />
+ <!-- no translation found for pref_security_passwords_title (5734190542383756711) -->
+ <skip />
+ <string name="pref_security_remember_passwords" msgid="6492957683454529549">"Ingat kata laluan"</string>
+ <!-- no translation found for pref_security_remember_passwords_summary (256388703356349137) -->
+ <skip />
+ <string name="pref_security_save_form_data" msgid="1213669802810198893">"Ingat data borang"</string>
+ <string name="pref_security_save_form_data_summary" msgid="4994074685153708026">"Ingat data yang saya taipkan dalam borang untuk kegunaan akan datang"</string>
+ <string name="pref_security_show_security_warning" msgid="8901135676266754559">"Tunjukkan amaran keselamatan"</string>
+ <string name="pref_security_show_security_warning_summary" msgid="8968906112720511704">"Tunjukkan amaran jika terdapat masalah dengan keselamatan tapak"</string>
+ <string name="pref_security_accept_cookies" msgid="3201367661925047989">"Terima kuki"</string>
+ <string name="pref_security_accept_cookies_summary" msgid="1465118934875026920">"Benarkan tapak menyimpan dan membaca data \"kuki\""</string>
+ <string name="pref_text_size" msgid="3827031324346612208">"Saiz teks"</string>
+ <string-array name="pref_text_size_choices">
+ <item msgid="4952686548944739548">"Sangat kecil"</item>
+ <item msgid="1950030433642671460">"Kecil"</item>
+ <item msgid="4338347520133294584">"Biasa"</item>
+ <item msgid="5043128215356351184">"Besar"</item>
+ <item msgid="7201512237890458902">"Sangat Besar"</item>
+ </string-array>
+ <string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Saiz teks"</string>
+ <!-- no translation found for pref_min_font_size (8811125835817449131) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable (5641500562399892621) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable_summary (4431962409438162448) -->
+ <skip />
+ <string name="pref_default_zoom" msgid="8076142259097187395">"Zum lalai"</string>
+ <string-array name="pref_default_zoom_choices">
+ <item msgid="549583171195154919">"Jauh"</item>
+ <item msgid="5619034257768161024">"Sederhana"</item>
+ <item msgid="3840999588443167001">"Dekat"</item>
+ </string-array>
+ <string name="pref_default_zoom_dialogtitle" msgid="6095974367125109021">"Zum lalai"</string>
+ <!-- no translation found for pref_content_load_page (2219810141690955452) -->
+ <skip />
+ <!-- no translation found for pref_content_load_page_summary (8792093504054149369) -->
+ <skip />
+ <!-- outdated translation 3091250467679722382 --> <string name="pref_extras_title" msgid="7075456173747370647">"Tetapan terperinci"</string>
+ <!-- no translation found for pref_extras_website_settings (67866640052455549) -->
+ <skip />
+ <!-- no translation found for pref_extras_website_settings_summary (1656771443223494406) -->
+ <skip />
+ <!-- no translation found for pref_extras_reset_default_title (3579760449455761762) -->
+ <skip />
+ <string name="pref_extras_reset_default" msgid="8904000515846202110">"Tetapkan semula kepada lalai"</string>
+ <!-- outdated translation 7984680562706914966 --> <string name="pref_extras_reset_default_summary" msgid="4247870778270414501">"Padam bersih semua data penyemak imbas dan tetapkan semula semua tetapan kepada lalai"</string>
+ <!-- no translation found for pref_extras_reset_default_dlg (6640261575874704022) -->
+ <skip />
+ <string name="pref_extras_reset_default_dlg_title" msgid="2250334970728938936">"Tetapkan semula kepada lalai"</string>
+ <string name="pref_development_title" msgid="3263854204533056480">"Nyahpepijat"</string>
+ <string name="pref_default_text_encoding" msgid="5742965543955558478">"Pengekodan teks"</string>
+ <!-- no translation found for pref_default_text_encoding_choices:2 (6122474363777211732) -->
+ <!-- no translation found for pref_default_text_encoding_choices:3 (373372275931607040) -->
+ <!-- no translation found for pref_default_text_encoding_choices:4 (891615911084608570) -->
+ <!-- no translation found for pref_default_text_encoding_choices:5 (5589150448475151241) -->
+ <!-- no translation found for pref_default_text_encoding_choices:6 (7356792686950371843) -->
+ <!-- no translation found for pref_default_text_encoding_choices:7 (2193955365569270096) -->
+ <string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Pengekodan teks"</string>
+ <!-- no translation found for pref_accessibility_title (5127836981587423215) -->
+ <skip />
+ <!-- no translation found for pref_lab_title (5571091610359629423) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls (3267606522082281367) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls_summary (1564546156544675707) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage (7597766876952506909) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage_summary (4132511544800457513) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search (1119176077760723740) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search_summary (839320474961917522) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen (8173609016657987973) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen_summary (6853711692160711419) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher (9063310468293037499) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher_summary (1782363693543953474) -->
+ <skip />
+ <!-- no translation found for help_useragent_switcher (123586256526014375) -->
+ <skip />
+ <string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Masalah kesambungan data"</string>
+ <string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Masalah dengan fail"</string>
+ <string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Sahkan"</string>
+ <string name="browserFrameFormResubmitMessage" msgid="2752182215695632138">"Halaman yang anda cuba paparkan mengandungi data yang sudah pun diserahkan (\"POSTDATA\"). Jika anda menghantar semula data itu, sebarang tindakan yang dijalankan borang pada halaman itu (seperti carian atau pembelian dalam talian) akan diulangi."</string>
+ <string name="loadSuspendedTitle" msgid="675991625288706944">"Tiada sambungan rangkaian"</string>
+ <!-- no translation found for loadSuspended (3133656588880851273) -->
+ <skip />
+ <string name="clear_history" msgid="5998307092715979619">"Padam bersih sejarah"</string>
+ <!-- no translation found for browser_history (1038987118290272525) -->
+ <skip />
+ <string name="empty_history" msgid="8738772352308207274">"Sejarah penyemak imbas kosong."</string>
+ <string name="add_new_bookmark" msgid="8086367791400349049">"Tambah penanda halaman..."</string>
+ <!-- no translation found for add_bookmark_short (3783984330998103735) -->
+ <skip />
+ <!-- no translation found for search_hint (4647356319916631820) -->
+ <skip />
+ <string name="search_button_text" msgid="5235226933877634410">"Pergi"</string>
+ <!-- no translation found for search_settings_description (1422401062529014107) -->
+ <skip />
+ <string name="attention" msgid="3473639060042811244">"Perhatian"</string>
+ <string name="popup_window_attempt" msgid="2673111696288657989">"Tapak ini cuba membuka tetingkap pop timbul."</string>
+ <string name="allow" msgid="1157313689171991335">"Benarkan"</string>
+ <string name="block" msgid="9172175889884707800">"Sekat"</string>
+ <string name="too_many_windows_dialog_title" msgid="5175503564948906442">"Had tetingkap dicapai"</string>
+ <string name="too_many_windows_dialog_message" msgid="1398571800233959583">"Tidak dapat membuka tetingkap baru kerana anda telah membuka bilangan maksimum tetingkap."</string>
+ <string name="too_many_subwindows_dialog_title" msgid="3805453941587725944">"Pop-up sudah terbuka"</string>
+ <string name="too_many_subwindows_dialog_message" msgid="5827289829907966657">"Tidak boleh membuka tetingkap pop-up baru kerana hanya satu sahaja yang boleh dibuka pada satu-satu masa."</string>
+ <string name="download_title" msgid="2122874021047565594">"Sejarah muat turun"</string>
+ <string name="download_unknown_filename" msgid="4013465542563652175">"<Tidak diketahui>"</string>
+ <string name="download_menu_open" msgid="4888327480367757513">"Buka"</string>
+ <string name="download_menu_clear" msgid="6264454531553418124">"Padam bersih daripada senarai"</string>
+ <!-- no translation found for download_menu_delete (8815502136393894148) -->
+ <skip />
+ <string name="download_menu_cancel" msgid="2545333007601851574">"Batalkan muat turun"</string>
+ <string name="download_menu_cancel_all" msgid="2136550823151999166">"Batalkan semua muat turun"</string>
+ <string name="download_cancel_dlg_title" msgid="8909108500262799748">"Batalkan muat turun"</string>
+ <string name="download_cancel_dlg_msg" msgid="6285389170052357797">"Semua <xliff:g id="DOWNLOAD_COUNT">%d</xliff:g> muat turun akan dibatalkan dan dipadam bersih daripada sejarah muat turun."</string>
+ <!-- no translation found for download_delete_file (5330036497843073249) -->
+ <skip />
+ <string name="download_file_error_dlg_title" msgid="2693630283595384874">"Kehabisan ruang"</string>
+ <string name="download_file_error_dlg_msg" msgid="5156405410324072471">"<xliff:g id="FILENAME">%s</xliff:g> tidak boleh dimuat turun."\n"Kosongkan sebahagian ruang pada telefon anda dan cuba lagi."</string>
+ <string name="download_failed_generic_dlg_title" msgid="6106781095337833391">"Muat turun tidak berjaya"</string>
+ <!-- outdated translation 605904452159416792 --> <string name="download_no_sdcard_dlg_title" product="nosdcard" msgid="56777245081568508">"Tiada kad SD"</string>
+ <string name="download_no_sdcard_dlg_title" product="default" msgid="605904452159416792">"Tiada kad SD"</string>
+ <!-- no translation found for download_no_sdcard_dlg_msg (3144652102051031721) -->
+ <skip />
+ <string name="download_no_sdcard_dlg_msg" product="default" msgid="2616399456116301518">"Kad SD diperlukan untuk memuat turun <xliff:g id="FILENAME">%s</xliff:g>."</string>
+ <!-- outdated translation 6877712666046917741 --> <string name="download_sdcard_busy_dlg_title" product="nosdcard" msgid="8081445664689818973">"Kad SD tidak tersedia"</string>
+ <string name="download_sdcard_busy_dlg_title" product="default" msgid="6877712666046917741">"Kad SD tidak tersedia"</string>
+ <!-- outdated translation 3473883538192835204 --> <string name="download_sdcard_busy_dlg_msg" product="nosdcard" msgid="3979329954835690147">"Kad SD sibuk. Untuk membenarkan muat turun, pilih \"Matikan storan USB\" dalam pemberitahuan."</string>
+ <string name="download_sdcard_busy_dlg_msg" product="default" msgid="3473883538192835204">"Kad SD sibuk. Untuk membenarkan muat turun, pilih \"Matikan storan USB\" dalam pemberitahuan."</string>
+ <!-- no translation found for cannot_download (8150552478556798780) -->
+ <skip />
+ <!-- no translation found for download_no_application_title (1286056729168874295) -->
+ <skip />
+ <string name="retry" msgid="1835923075542266721">"Cuba semula"</string>
+ <string name="no_downloads" msgid="3947445710685021498">"Sejarah muat turun kosong."</string>
+ <string name="download_error" msgid="413496839831257187">"Download tidak berjaya."</string>
+ <string name="download_success" msgid="2279041638155595203">"Muat turun <xliff:g id="FILE">%s</xliff:g> selesai."</string>
+ <string name="download_running" msgid="2622942231322015059">"Memuat turun..."</string>
+ <string name="download_pending" msgid="2599683668575349559">"Memulakan muat turun ..."</string>
+ <string name="download_pending_network" msgid="6548714525679461053">"Menunggu sambungan data..."</string>
+ <string name="download_running_paused" msgid="6418029352085656495">"Menunggu sambungan data..."</string>
+ <string name="download_canceled" msgid="6057083743144492515">"Muat turun dibatalkan."</string>
+ <!-- no translation found for download_not_acceptable (313769696131563652) -->
+ <skip />
+ <string name="download_file_error" msgid="1206648050615176113">"Tidak boleh menyelesaikan muat turun. Ruang tidak mencukupi."</string>
+ <string name="download_length_required" msgid="9038605488460437406">"Tidak boleh memuat turun. Saiz item tidak boleh ditentukan."</string>
+ <string name="download_precondition_failed" msgid="8327584102874295580">"Muat turun terganggu. Ia tidak boleh disambung semula."</string>
+ <string name="search_the_web" msgid="6046130189241962337">"Cari di web"</string>
+ <!-- no translation found for webstorage_outofspace_notification_title (1160474608059771788) -->
+ <skip />
+ <!-- no translation found for webstorage_outofspace_notification_text (7341075135051829692) -->
+ <skip />
+ <!-- no translation found for webstorage_clear_data_title (689484577124333977) -->
+ <skip />
+ <!-- no translation found for webstorage_clear_data_dialog_title (345457466368974706) -->
+ <skip />
+ <!-- no translation found for webstorage_clear_data_dialog_message (6678281256970470125) -->
+ <skip />
+ <!-- no translation found for webstorage_clear_data_dialog_ok_button (2516563534211898636) -->
+ <skip />
+ <!-- no translation found for webstorage_clear_data_dialog_cancel_button (2028867751958942762) -->
+ <skip />
+ <!-- no translation found for webstorage_origin_summary_mb_stored (1985885826292236210) -->
+ <skip />
+ <!-- no translation found for loading_video (4887871585216091096) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_message (356796102004052471) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_share (9084486342048347976) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_dont_share (6303025160237860300) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_remember (3118526300707348308) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_toast_allowed (987286072035125498) -->
+ <skip />
+ <!-- no translation found for geolocation_permissions_prompt_toast_disallowed (7695100950212692515) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_title (1745477985097536528) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_summary_allowed (9180251524290811398) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_summary_not_allowed (4589649082203102544) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_dialog_title (1549842043381347668) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_dialog_message (7586671987576403993) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_dialog_ok_button (4789434178048077287) -->
+ <skip />
+ <!-- no translation found for geolocation_settings_page_dialog_cancel_button (7941036504673409747) -->
+ <skip />
+ <!-- no translation found for website_settings_clear_all (8739804325997655980) -->
+ <skip />
+ <!-- no translation found for website_settings_clear_all_dialog_title (7791826325122461718) -->
+ <skip />
+ <!-- no translation found for website_settings_clear_all_dialog_message (6150502090601476333) -->
+ <skip />
+ <!-- no translation found for website_settings_clear_all_dialog_ok_button (6401582240627669431) -->
+ <skip />
+ <!-- no translation found for website_settings_clear_all_dialog_cancel_button (1896757051856611674) -->
+ <skip />
+ <!-- no translation found for progress_dialog_setting_wallpaper (4871900779338536674) -->
+ <skip />
+ <!-- no translation found for defaultBookmarksUpButton (2303951020715704735) -->
+ <skip />
+ <!-- no translation found for empty_bookmarks_folder (7843361614634930942) -->
+ <skip />
+ <!-- no translation found for rlz_access_point (7165847807377650632) -->
+ <skip />
+ <!-- no translation found for account_chooser_dialog_title (3314204833188808194) -->
+ <!-- no translation found for account_chooser_dialog_title (4833571985009544332) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_title (3325557652271172128) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_description (1942452375564381488) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_select_add_account (3102882579089291099) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_delete_select_account (5192284761080626386) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_delete (8854001080444749211) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_add (5433677293195372675) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_remove (5984607822851800902) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_next (7578143961884352676) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_previous (8551440353688257031) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_cancel (4936061122806506634) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_done (1446247092194489191) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_add (7552306756868669353) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_import (6933613853573899218) -->
+ <skip />
+ <!-- no translation found for menu_share_url (5851814357333739700) -->
+ <skip />
+ <!-- no translation found for max_tabs_warning (4122034303809457570) -->
+ <skip />
+ <!-- no translation found for instant_search_label (8769284297650716935) -->
+ <skip />
+ <!-- no translation found for recover_title (8095611702406163360) -->
+ <skip />
+ <!-- no translation found for recover_prompt (5526783279696786755) -->
+ <skip />
+ <!-- no translation found for recover_yes (5837971910598069183) -->
+ <skip />
+ <!-- no translation found for recover_no (3121030267940592611) -->
+ <skip />
+ <!-- no translation found for preview (1470306351083271066) -->
+ <skip />
+ <!-- no translation found for local_bookmarks (533816851415228520) -->
+ <skip />
+</resources>
diff --git a/res/values-nb-sw600dp/strings.xml b/res/values-nb-sw600dp/strings.xml
index 421bb88..d82c50f 100644
--- a/res/values-nb-sw600dp/strings.xml
+++ b/res/values-nb-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Åpne i ny bakgrunnsfane"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Åpne alle i nye faner"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Åpne nye faner bak den gjeldende"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vil du gjenopprette fanene?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Nettleseren ser ut til å ha fått et programstopp. Vil du gjenopprette fanene fra forrige økt?"</string>
</resources>
diff --git a/res/values-nb-xlarge/strings.xml b/res/values-nb-xlarge/strings.xml
index 67ab1b6..507fab4 100644
--- a/res/values-nb-xlarge/strings.xml
+++ b/res/values-nb-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Åpne i ny bakgrunnsfane"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Åpne alle i nye faner"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Åpne nye faner bak den gjeldende"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vil du gjenopprette fanene?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Nettleseren ser ut til å ha fått et programstopp. Vil du gjenopprette fanene fra forrige økt?"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 18007c7..597c051 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Avbryt"</string>
<string name="location" msgid="3411848697912600125">"Adresse"</string>
+ <string name="account" msgid="5179824606448077042">"Konto"</string>
<string name="containing_folder" msgid="6771180232953030479">"Legg til i"</string>
<string name="new_folder" msgid="7743540149088867917">"Ny mappe"</string>
<string name="edit_folder" msgid="621817453133656156">"Rediger mappe"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Skriv inn og lagre data for automatisk utfylling av nettskjemafelter"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatisk Google-pålogging"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Pålogging til Google-nettsteder ved hjelp av <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatisk pålogging er tilgjengelig."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Logg på som"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Logg på"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Skjul"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Pålogging mislyktes."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Skriv inn dataene du vil fylle inn automatisk når du trykker på felter på nettet."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Fullt navn:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Kjempestor"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tekststørrelse"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minste skriftstørrelse"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Tving aktivering av zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Hvorvidt et nettsteds forespørs. om å kontr. zoom-adferd skal overstyres"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Standardzoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Langt unna"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Koreansk (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Tekstkoding"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Tilgjengelighet"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Prøvefunksjoner"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Hurtigkontroller"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Sveip fra venstre mot høyre kant for å bruke hurtigkontr. og skjule app- og nettadresserader"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Startsiden viser dine mest besøkte nettsider."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Bruk Google Instant når du bruker Google Søk for å vise resultater mens du skriver (dette kan gi økt databruk)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Fullskjerm"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Bruk fullskjermmodus for å skjule statusfeltet."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Veksling av brukeragent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Veksle mellom nettbrett- og skrivebordsversjonen av et nettsted."</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Trykk på ikonet for Android eller bærbar datamaskin for å veksle mellom nettbrett- og skrivebordsversjonen av et nettsted."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Datatilkoblingsproblem"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem med fil"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Bekreft"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Del"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Ingen flere faner tilgjengelig"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google med Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vil du gjenopprette vinduene?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Nettleseren ser ut til å ha fått et programstopp. Vil du gjenopprette vinduene fra forrige økt?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ja"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nei"</string>
+ <string name="preview" msgid="1470306351083271066">"Forhåndsvisning:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokal"</string>
</resources>
diff --git a/res/values-nl-sw600dp/strings.xml b/res/values-nl-sw600dp/strings.xml
index 59c7ad5..4947df5 100644
--- a/res/values-nl-sw600dp/strings.xml
+++ b/res/values-nl-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Openen op een nieuw tabblad op de achtergrond"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Alle bladwijzers openen op nieuwe tabbladen"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Nieuwe tabbladen openen achter het huidige tabblad"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Tabbladen herstellen?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"De browser lijkt te zijn gecrasht. Wilt u de tabbladen uit uw vorige sessie herstellen?"</string>
</resources>
diff --git a/res/values-nl-xlarge/strings.xml b/res/values-nl-xlarge/strings.xml
index ea78890..16d5032 100644
--- a/res/values-nl-xlarge/strings.xml
+++ b/res/values-nl-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Openen op een nieuw tabblad op de achtergrond"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Alle bladwijzers openen op nieuwe tabbladen"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Nieuwe tabbladen openen achter het huidige tabblad"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Tabbladen herstellen?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"De browser lijkt te zijn gecrasht. Wilt u de tabbladen uit uw vorige sessie herstellen?"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 8c25469..abb4a5d 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Annuleren"</string>
<string name="location" msgid="3411848697912600125">"Adres"</string>
+ <string name="account" msgid="5179824606448077042">"Account"</string>
<string name="containing_folder" msgid="6771180232953030479">"Toevoegen aan"</string>
<string name="new_folder" msgid="7743540149088867917">"Nieuwe map"</string>
<string name="edit_folder" msgid="621817453133656156">"Map bewerken"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Gegevens invoeren en opslaan voor automatisch invullen van velden in webformulieren"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatische Google-aanmelding"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Aanmelden bij Google-sites met <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatisch aanmelden is beschikbaar."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Aanmelden als"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Aanmelden"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Verbergen"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Aanmelden mislukt."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Geef de gegevens op die u automatisch in webvelden wilt laten invullen wanneer u ze aanraakt."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Volledige naam:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Enorm"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tekengrootte"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimum lettergrootte"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Zoom inschakelen forceren"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Of websiteverzoek tot bepalen van zoomgedrag wordt genegeerd"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Standaardzoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Veraf"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Koreaans (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Tekstcodering"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Toegankelijkheid"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Snelle bedieningselementen"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Schuif vanaf links of rechts voor Quick Controls en om app- en URL-balken te verbergen"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Op uw startpagina staan uw meest bezochte webpagina\'s."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Gebruik Google Instant bij Google Zoeken voor resultaten tijdens het typen (kan resulteren in meer gegevensverbruik)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Volledig scherm"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Gebruik de modus voor volledig scherm om de statusbalk te verbergen."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Schakelen tussen de tablet- en desktopversies van een site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tik op het Android- of laptop-pictogram om te schakelen tussen de tablet- en desktopversies van een site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Probleem met gegevensverbinding"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Probleem met bestand"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Bevestigen"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Delen"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Er zijn niet meer tabbladen beschikbaar"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google met Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vensters herstellen?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"De browser lijkt te zijn gecrasht. Wilt u de vensters uit uw vorige sessie herstellen?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ja"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nee"</string>
+ <string name="preview" msgid="1470306351083271066">"Voorbeeld:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokaal"</string>
</resources>
diff --git a/res/values-pl-sw600dp/strings.xml b/res/values-pl-sw600dp/strings.xml
index 217276e..52b7e5c 100644
--- a/res/values-pl-sw600dp/strings.xml
+++ b/res/values-pl-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Otwórz w nowej karcie tła"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Otwórz wszystkie w nowych kartach"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Otwieraj nowe karty za bieżącą"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Przywrócić karty?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Przeglądarka uległa prawdopodobnie awarii. Czy chcesz przywrócić karty z poprzedniej sesji?"</string>
</resources>
diff --git a/res/values-pl-xlarge/strings.xml b/res/values-pl-xlarge/strings.xml
index d5fe8e5..33c1eb9 100644
--- a/res/values-pl-xlarge/strings.xml
+++ b/res/values-pl-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Otwórz w nowej karcie tła"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Otwórz wszystkie w nowych kartach"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Otwieraj nowe karty za bieżącą"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Przywrócić karty?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Przeglądarka uległa awarii. Czy chcesz przywrócić karty z poprzedniej sesji?"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index e686328..23ee6d7 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Anuluj"</string>
<string name="location" msgid="3411848697912600125">"Adres"</string>
+ <string name="account" msgid="5179824606448077042">"Konto"</string>
<string name="containing_folder" msgid="6771180232953030479">"Dodaj do"</string>
<string name="new_folder" msgid="7743540149088867917">"Nowy folder"</string>
<string name="edit_folder" msgid="621817453133656156">"Edytuj folder"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Wpisz i zachowaj dane, które chcesz automatycznie uzupełniać w formularzach internetowych"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatyczne logowanie do Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Logowanie w witrynach Google za pomocą identyfikatora <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatyczne logowanie jest dostępne."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Zaloguj jako"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Zaloguj"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ukryj"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Niepowodzenie logowania."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Wprowadź dane, które chcesz automatycznie umieszczać w formularzach internetowych."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Imię i nazwisko:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Bardzo duży"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Rozmiar tekstu"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimalny rozmiar czcionki"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Wymuś włączenie powiększenia"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Określa, czy zezwolić stronie na sterowanie powiększeniem"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Powiększenie domyślne"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Małe"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"koreański (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Kodowanie tekstu"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Ułatwienia dostępu"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laboratorium"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Szybkie sterowanie"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Przesuń kciukiem od lewej lub prawej, aby użyć szybkiego sterowania oraz ukryć paski aplikacji i URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Na stronie głównej wyświetlane są najczęściej odwiedzane strony internetowe."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Wyszukiwanie dynamiczne Google"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Użyj wyszukiwania dynamicznego Google, aby uzyskiwać wyniki podczas pisania (może być pobierana większa ilość danych)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Pełny ekran"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Użyj trybu pełnoekranowego, aby ukryć pasek stanu."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Przełączanie ciągu agenta użytkownika"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Przełączanie widoku między wersjami witryny dla tabletu i komputera"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Dotknij ikony systemu Android lub laptopa, aby przełączyć widok między wersjami witryny dla tabletu i komputera."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problem z łącznością danych"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem z plikiem"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Potwierdzenie"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Udostępnij"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Brak dostępnych kart"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google z wyszukiwaniem dynamicznym (Laboratorium)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Przywrócić okna?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Przeglądarka uległa awarii. Czy chcesz przywrócić okna z poprzedniej sesji?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Tak"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nie"</string>
+ <string name="preview" msgid="1470306351083271066">"Podgląd:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokalne"</string>
</resources>
diff --git a/res/values-pt-rPT-sw600dp/strings.xml b/res/values-pt-rPT-sw600dp/strings.xml
index 3598b7b..484c165 100644
--- a/res/values-pt-rPT-sw600dp/strings.xml
+++ b/res/values-pt-rPT-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Abrir num separador novo em segundo plano"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Abrir tudo em separadores novos"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Abrir novos separadores atrás do atual"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Restaurar separadores?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"O navegador bloqueou. Pretende restaurar os separadores abertos na última sessão?"</string>
</resources>
diff --git a/res/values-pt-rPT-xlarge/strings.xml b/res/values-pt-rPT-xlarge/strings.xml
index 5c45d17..fac7ed3 100644
--- a/res/values-pt-rPT-xlarge/strings.xml
+++ b/res/values-pt-rPT-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Abrir em novo separador em segundo plano"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Abrir tudo em separadores novos"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Abrir novos separadores atrás do actual"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Restaurar separadores?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"O navegador bloqueou. Pretende restaurar os separadores utilizados na última sessão?"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a9017fb..72b2548 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancelar"</string>
<string name="location" msgid="3411848697912600125">"Endereço"</string>
+ <string name="account" msgid="5179824606448077042">"Conta"</string>
<string name="containing_folder" msgid="6771180232953030479">"Adicionar a"</string>
<string name="new_folder" msgid="7743540149088867917">"Nova pasta"</string>
<string name="edit_folder" msgid="621817453133656156">"Editar pasta"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Introduzir e guardar dados de campos de formulários Web de preenchimento automático"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Início sessão automático Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Iniciar sessão em Web sites do Google utilizando <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Início sessão automático disponível."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Iniciar sessão como"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"In. sessão"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ocultar"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Falha ao iniciar sessão."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Introduza os dados que pretende preencher automaticamente nos campos Web quando tocar nos mesmos."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nome completo:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Muito grande"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tamanho do texto"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Tamanho mín. do tipo de letra"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Forçar ativação do zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Eliminar ou não pedido do site para controlar zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predefinido"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Afastado"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreano (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificação do texto"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Acessibilidade"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controlos rápidos"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Deslize polegar margem esq. ou dir. p/ aceder contr. rápidos e ocultar barras Aplicação e URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"A sua página inicial apresenta as páginas Web mais visitadas."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instantâneo"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Utilize Google Instantâneo na Pesquisa do Google para mostrar resultados quando escreve (pode aumentar utiliz. dados)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Ecrã inteiro"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Utilizar o modo de ecrã inteiro para ocultar a barra de estado."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Alternar entre as versões de tablet e de computador de um Web site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Toque no ícone do Android ou no ícone do computador portátil para alternar entre as versões de tablet e de computador de um Web site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema de conectividade de dados"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problemas com o ficheiro"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirmar"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Partilhar"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Atingiu o limite de separadores"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google com Instantâneo (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Restaurar as janelas?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"O navegador bloqueou. Pretende restaurar as janelas utilizadas na última sessão?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sim"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Não"</string>
+ <string name="preview" msgid="1470306351083271066">"Pré-visualizar:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Local"</string>
</resources>
diff --git a/res/values-pt-sw600dp/strings.xml b/res/values-pt-sw600dp/strings.xml
index 2cfc851..53917a0 100644
--- a/res/values-pt-sw600dp/strings.xml
+++ b/res/values-pt-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Abrir em uma nova guia em segundo plano"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Abrir tudo em novas guias"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Abrir novas guias atrás da guia atual"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Restaurar guias?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Parece que o navegador travou. Restaurar as guias da última sessão?"</string>
</resources>
diff --git a/res/values-pt-xlarge/strings.xml b/res/values-pt-xlarge/strings.xml
index 73dfece..a729b61 100644
--- a/res/values-pt-xlarge/strings.xml
+++ b/res/values-pt-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Abrir em uma nova guia em segundo plano"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Abrir todos em novas abas"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Abrir novas guias atrás da guia atual"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Restaurar guias?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"O navegador parece ter travado. Gostaria de restaurar as guias da última vez?"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index baa56ab..58fa411 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Cancelar"</string>
<string name="location" msgid="3411848697912600125">"Endereço"</string>
+ <string name="account" msgid="5179824606448077042">"Conta"</string>
<string name="containing_folder" msgid="6771180232953030479">"Adicionar a"</string>
<string name="new_folder" msgid="7743540149088867917">"Nova pasta"</string>
<string name="edit_folder" msgid="621817453133656156">"Editar pasta"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Inserir e salvar dados para preencher automaticamente os campos dos formulários da web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Login automático do Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Faça login nos sites do Google usando <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"O login automático está disponível."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Fazer login como"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Fazer login"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ocultar"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Falha de login."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Insira os dados que deseja preencher automaticamente em campos da web ao tocá-los."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Nome completo:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Enorme"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Tamanho do texto"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Tamanho mínimo da fonte"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Forçar ativação de zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Subst. ou não solic. do site para contr. zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom padrão"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Longe"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreano (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificação de texto"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Acessibilidade"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Google Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Controles rápidos"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Deslize o polegar da esqu. ou dir. para acessar controles rápidos e ocultar barras de apps e URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Sua página inicial exibe as páginas da web mais visitadas."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Use o Google Instant ao usar a Pesquisa Google para exibir resultados enquanto digita (o uso de dados pode aumentar)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Tela cheia"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Use o modo de tela cheia para ocultar a barra de status."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Alternador de agente de usuário"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Alternar entre as versões para tablet e computador de um site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Toque no Android ou no ícone do laptop para alternar entre as versões de um site para tablet e computador."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema de conectividade de dados"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problema com o arquivo"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirmar"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Compartilhar"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Não há mais guias disponíveis"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google com Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Restaurar janelas?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"O navegador parece ter travado. Gostaria de restaurar as janelas da última vez?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Sim"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Não"</string>
+ <string name="preview" msgid="1470306351083271066">"Visualizar:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Locais"</string>
</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 5cabaa0..eeaec0a 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -67,6 +67,8 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Interrumper"</string>
<!-- outdated translation 969988560160364559 --> <string name="location" msgid="3411848697912600125">"Adressa"</string>
+ <!-- no translation found for account (5179824606448077042) -->
+ <skip />
<!-- no translation found for containing_folder (6771180232953030479) -->
<skip />
<!-- no translation found for new_folder (7743540149088867917) -->
@@ -210,10 +212,12 @@
<skip />
<!-- no translation found for pref_autologin_progress (8333244467048833461) -->
<skip />
- <!-- no translation found for autologin_bar_text (8013977161879448141) -->
+ <!-- no translation found for autologin_bar_text (3684581827167173371) -->
<skip />
<!-- no translation found for autologin_bar_login_text (7052816600314556734) -->
<skip />
+ <!-- no translation found for autologin_bar_hide_text (3629355974385859580) -->
+ <skip />
<!-- no translation found for autologin_bar_error (5132514366023044839) -->
<skip />
<!-- no translation found for autofill_profile_editor_heading (8392952553626722083) -->
@@ -305,6 +309,12 @@
<item msgid="7201512237890458902">"Fitg grond"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Grondezza dal text"</string>
+ <!-- no translation found for pref_min_font_size (8811125835817449131) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable (5641500562399892621) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable_summary (4431962409438162448) -->
+ <skip />
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom predefinì"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lontan"</item>
@@ -336,6 +346,8 @@
<item msgid="2193955365569270096">"Corean (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codaziun dal text"</string>
+ <!-- no translation found for pref_accessibility_title (5127836981587423215) -->
+ <skip />
<!-- no translation found for pref_lab_title (5571091610359629423) -->
<skip />
<!-- no translation found for pref_lab_quick_controls (3267606522082281367) -->
@@ -350,6 +362,16 @@
<skip />
<!-- no translation found for pref_use_instant_search_summary (839320474961917522) -->
<skip />
+ <!-- no translation found for pref_lab_fullscreen (8173609016657987973) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen_summary (6853711692160711419) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher (9063310468293037499) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher_summary (1782363693543953474) -->
+ <skip />
+ <!-- no translation found for help_useragent_switcher (123586256526014375) -->
+ <skip />
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problem da connectivitad da datas"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem da datoteca"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confermar"</string>
@@ -478,4 +500,16 @@
<skip />
<!-- no translation found for instant_search_label (8769284297650716935) -->
<skip />
+ <!-- no translation found for recover_title (8095611702406163360) -->
+ <skip />
+ <!-- no translation found for recover_prompt (5526783279696786755) -->
+ <skip />
+ <!-- no translation found for recover_yes (5837971910598069183) -->
+ <skip />
+ <!-- no translation found for recover_no (3121030267940592611) -->
+ <skip />
+ <!-- no translation found for preview (1470306351083271066) -->
+ <skip />
+ <!-- no translation found for local_bookmarks (533816851415228520) -->
+ <skip />
</resources>
diff --git a/res/values-ro-sw600dp/strings.xml b/res/values-ro-sw600dp/strings.xml
index a6f9874..0bb9608 100644
--- a/res/values-ro-sw600dp/strings.xml
+++ b/res/values-ro-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Deschideţi într-o filă nouă în fundal"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Deschideţi-le pe toate în file noi"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Deschideţi filele noi în spatele celei curente"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Restabiliţi filele?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Browserul pare să se fi blocat. Doriţi să restabiliţi filele din ultima sesiune?"</string>
</resources>
diff --git a/res/values-ro-xlarge/strings.xml b/res/values-ro-xlarge/strings.xml
index a7d3698..a5e2a8e 100644
--- a/res/values-ro-xlarge/strings.xml
+++ b/res/values-ro-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Deschideţi într-o filă nouă în fundal"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Deschideţi-le pe toate în file noi"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Deschideţi file noi în spatele celei curente"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Restabiliţi filele?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Browserul pare să se fi blocat. Doriţi să restabiliţi filele din ultima sesiune?"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 53c3e97..9734215 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Anulaţi"</string>
<string name="location" msgid="3411848697912600125">"Adresă"</string>
+ <string name="account" msgid="5179824606448077042">"Cont"</string>
<string name="containing_folder" msgid="6771180232953030479">"Adăugaţi la"</string>
<string name="new_folder" msgid="7743540149088867917">"Dosar nou"</string>
<string name="edit_folder" msgid="621817453133656156">"Editaţi dosarul"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Introduceţi şi salvaţi date pentru completarea automată a câmpurilor din formularele web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Conectare automată la Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Se conectează la site-urile Google utilizând <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Este disponibilă conectarea automată."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Conectaţi-vă ca"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Conectare"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ascundeţi"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Conectare eşuată."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Introduceţi datele care se vor completa automat în câmpurile web, atunci când le atingeţi."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Numele complet:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Foarte mare"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Dimensiune text"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Dimensiunea minimă a fontului"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Forţaţi activarea zoomului"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Suprascriere solicitare site web pentru control comportament zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Zoom prestabilit"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Departe"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Coreeană (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Codificare text"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Accesibilitate"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laborator"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Comenzi rapide"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Glis. deg. mare din marg. st. sau dr. şi acc. com. rapide/asc. bar. Apl. şi URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Pagina dvs. de pornire afişează paginile web cele mai accesate."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Utilizaţi Google Instant în Căutarea Google şi vedeţi rezultate în timp ce introd. text (creşte vol. de date utilizate)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Ecran complet"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Utilizaţi modul ecran complet pentru a ascunde bara de stare."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Comutator UserAgent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Comutaţi între versiunea pentru tabletă şi cea pentru desktop ale unui site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Apăsaţi pe pictograma Android sau laptop pentru a comuta între versiunea pentru tabletă şi cea pentru desktop ale unui site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Există o problemă de conexiune la date"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problemă cu fişierul"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Confirmaţi"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Distribuiţi"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Nu mai există file disponibile"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google cu Instant (Google Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Restabiliţi ferestrele?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Browserul pare să se fi blocat. Doriţi să restabiliţi ferestrele din ultima sesiune?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Da"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nu"</string>
+ <string name="preview" msgid="1470306351083271066">"Previzualizaţi:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Locale"</string>
</resources>
diff --git a/res/values-ru-sw600dp/strings.xml b/res/values-ru-sw600dp/strings.xml
index 85a4357..73cf2e0 100644
--- a/res/values-ru-sw600dp/strings.xml
+++ b/res/values-ru-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Открыть в фоновой вкладке"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Открыть все в новых вкладках"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Открывать новые вкладки позади текущей"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Восстановить вкладки?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Произошел сбой в работе браузера. Восстановить вкладки последнего сеанса?"</string>
</resources>
diff --git a/res/values-ru-xlarge/strings.xml b/res/values-ru-xlarge/strings.xml
index 517957e..9fad6d2 100644
--- a/res/values-ru-xlarge/strings.xml
+++ b/res/values-ru-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Открыть в фоновой вкладке"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Открыть все в новых вкладках"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Открывать новые вкладки под текущей вкладкой"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Восстановить вкладки?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Произошел сбой в работе браузера. Восстановить вкладки последнего сеанса?"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index ce6c856..b7fc4a9 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"ОК"</string>
<string name="do_not_save" msgid="6777633870113477714">"Отмена"</string>
<string name="location" msgid="3411848697912600125">"Адрес"</string>
+ <string name="account" msgid="5179824606448077042">"Аккаунт"</string>
<string name="containing_folder" msgid="6771180232953030479">"Добавить в"</string>
<string name="new_folder" msgid="7743540149088867917">"Новая папка"</string>
<string name="edit_folder" msgid="621817453133656156">"Изменить папку"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Ввод и сохранение данных для автозаполнения веб-форм"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Автоматический вход в Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Вход в Сайты Google с помощью аккаунта <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Доступен автоматический вход."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Войти как"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Войти"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Скрыть"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Вход не выполнен."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Вводите данные в веб-формы одним нажатием с помощью автозаполнения."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Полное имя:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Огромный"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Размер текста"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Минимальный размер шрифта"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Менять масштаб принудительно"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Учитывать ли запросы сайтов при управлении масштабом"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Масштаб по умолчанию"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Мелкий"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Корейская (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Кодировка текста"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Специальные возможности"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Лаборатория Google"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Панель инструментов"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Чтобы открыть панель инструментов, скрыв адресную строку и панель приложений, проведите пальцем в правом или левом углу экрана"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Отображение часто посещаемых веб-сайтов на стартовой странице."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Живой поиск"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"В Живом поиске результаты появляются прямо при вводе текста (возможно увеличение объема передаваемых данных)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Во весь экран"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Чтобы скрыть строку состояния, используйте полноэкранный режим."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"User Agent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Переключение между версиями сайта для планшетного ПК и для обычного компьютера"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Нажимайте на значки устройства Android или ноутбука, чтобы выбрать требуемую версию сайта – для планшетного ПК или для обычного компьютера."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Проблема с подключением"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Проблема с файлом"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Подтвердить"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Отправить"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Достигнут предел количества вкладок"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google с Живым поиском (Лаборатория Google)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Восстановить окна?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Произошел сбой в работе браузера. Восстановить окна последнего сеанса?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Да"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Нет"</string>
+ <string name="preview" msgid="1470306351083271066">"Просмотр"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Локальные"</string>
</resources>
diff --git a/res/values-sk-sw600dp/strings.xml b/res/values-sk-sw600dp/strings.xml
index f76492c..e7a80e4 100644
--- a/res/values-sk-sw600dp/strings.xml
+++ b/res/values-sk-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Otvoriť na novej karte na pozadí"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Otvoriť všetky na nových kartách"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Otvárať nové karty za aktuálnou kartou"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Obnoviť karty?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Zrejme došlo k zlyhaniu prehliadača. Chcete obnoviť naposledy otvorené karty?"</string>
</resources>
diff --git a/res/values-sk-xlarge/strings.xml b/res/values-sk-xlarge/strings.xml
index d1be7da..f9f9048 100644
--- a/res/values-sk-xlarge/strings.xml
+++ b/res/values-sk-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Otvoriť na novej karte na pozadí"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Otvoriť všetky na nových kartách"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Otvárať nové karty za aktuálnou kartou"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Obnoviť karty?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Zrejme došlo k zlyhaniu prehliadača. Chcete obnoviť naposledy otvorené karty?"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 12a0aed..8139ec7 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Zrušiť"</string>
<string name="location" msgid="3411848697912600125">"Adresa"</string>
+ <string name="account" msgid="5179824606448077042">"Účet"</string>
<string name="containing_folder" msgid="6771180232953030479">"Pridať do"</string>
<string name="new_folder" msgid="7743540149088867917">"Nový priečinok"</string>
<string name="edit_folder" msgid="621817453133656156">"Upraviť priečinok"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Zadajte a uložte údaje pre automatické dopĺňanie polí webových formulárov"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatické prihlasovanie Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Prihlasovanie na stránky Google pomocou používateľského mena <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatické prihlásenie je k dispozícii."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Prihlásený/-á ako"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Prihlásiť"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Skryť"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Prihlásenie zlyhalo."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Zadajte údaje, ktoré sa majú pri dotyku automaticky doplniť do webových polí."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Celé meno:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Veľmi veľký"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Veľkosť textu"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimálna veľkosť písma"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Vynút. povolenie priblíženia"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Prekonanie žiadosti lokality o ovládanie priblíženia"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Predvolené priblíženie"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Ďaleko"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Kórejčina (EUC–KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Kódovanie textu"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Zjednodušenie"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Rýchle ovládacie prvky"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Posuňte prstom v smere od ľavého alebo pravého okraja, čím rýchlo pristúpite k ovládacím prvkom a skryjete panely aplikácií a adresy URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Na vašej domovskej stránke sa zobrazujú najviac navštevované webové stránky."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Dynamické vyhľadávanie Google"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Ak chcete zobrazovať výsl. počas zadávania textu, použite Dynamické vyhľ. Google (môže sa zvýšiť spotr. údajov)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Celá obrazovka"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Ak chcete skryť stavový riadok, použite režim celej obrazovky."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Prepínanie medzi verziou stránok pre tablety a verziou pre počítače"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Klepnutím na ikonu Android alebo prenosný počítač môžete prepínať medzi verziou webových stránok pre tablety a verziou pre počítače."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problémy s dátovým pripojením"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problém so súborom"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Potvrdiť"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Zdieľať"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"K dispozícii nie sú žiadne ďalšie záložky"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google s Dynamickým vyhľadávaním (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Obnoviť okná?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Zrejme došlo k zlyhaniu prehliadača. Chcete obnoviť naposledy otvorené okná?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Áno"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nie"</string>
+ <string name="preview" msgid="1470306351083271066">"Ukážka:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Miestne"</string>
</resources>
diff --git a/res/values-sl-sw600dp/strings.xml b/res/values-sl-sw600dp/strings.xml
index 31f0310..44d98b4 100644
--- a/res/values-sl-sw600dp/strings.xml
+++ b/res/values-sl-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Odpri na novem zavihku v ozadju"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Odpri vse na novih zavihkih"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Odpri nove zavihke za trenutnim"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Želite obnoviti zavihke?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Videti je, da se je brskalnik zrušil. Želite obnoviti prejšnje zavihke?"</string>
</resources>
diff --git a/res/values-sl-xlarge/strings.xml b/res/values-sl-xlarge/strings.xml
index 55a76e4..bce1349 100644
--- a/res/values-sl-xlarge/strings.xml
+++ b/res/values-sl-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Odpri v novem zavihku v ozadju"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Odpri vse v novih zavihkih"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Odpri nove zavihke za trenutnim"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Želite obnoviti zavihke?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Videti je, da se je brskalnik zrušil. Želite obnoviti prejšnje zavihke?"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index b153da3..d3fd8aa 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"V redu"</string>
<string name="do_not_save" msgid="6777633870113477714">"Prekliči"</string>
<string name="location" msgid="3411848697912600125">"Naslov"</string>
+ <string name="account" msgid="5179824606448077042">"Račun"</string>
<string name="containing_folder" msgid="6771180232953030479">"Dodaj v skupino"</string>
<string name="new_folder" msgid="7743540149088867917">"Nova mapa"</string>
<string name="edit_folder" msgid="621817453133656156">"Uredi mapo"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Vnesite in shranite podatke za samodejno izpolnjevanje polj v spletnih obrazcih"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Samodejna prijava v Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Prijavljanje v Google Spletna mesta z <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Na voljo je samodejna prijava."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Prijava kot"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Prijava"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Skrij"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Prijava ni uspela."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Vnesite podatke, za katere želite, da se samodejno vnesejo v spletna polja, ko se jih dotaknete."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Polno ime:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Velikanska"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Velikost besedila"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Najmanjša velikost pisave"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Vsili povečavo"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Preglas. zaht. mesta za nadz. povečave?"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Privzeta povečava/pomanjšava"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Oddaljeno"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korejščina (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Kodiranje besedila"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Nastavitve za osebe s posebnimi potrebami"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Laboratoriji"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Hitri kontrolniki"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Povlecite palec z l./d. roba za hitre kontr. in skrivanje vrstic Program in URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Na domači strani so prikazane najpogosteje obiskane spletne strani."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Dinamično iskanje"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Če uporabljate Google Dinamično iskanje, se rezultati prikazujejo že med tipkanjem, kar lahko poveča porabo podatkov."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Celozaslonsko"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Če želite skriti vrstico stanja, uporabite celozaslonski način."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Preklapljanje uporabniških posrednikov"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Preklop med različicami mesta za tablični in za namizni računalnik"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Dotaknite se ikone za Android ali namizni računalnik, da preklopite med različicama mesta za tablične in za namizne računalnike."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Težava s povezljivostjo podatkov"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Težava z datoteko"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Potrdi"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Skupna raba"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Ni več razpoložljivih zavihkov"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google z Dinamičnim iskanjem (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Želite obnoviti okna?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Videti je, da se je brskalnik zrušil. Želite obnoviti prejšnja okna?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Da"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Ne"</string>
+ <string name="preview" msgid="1470306351083271066">"Predogled:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokalno"</string>
</resources>
diff --git a/res/values-sr-sw600dp/strings.xml b/res/values-sr-sw600dp/strings.xml
index 827e8e9..d82b91f 100644
--- a/res/values-sr-sw600dp/strings.xml
+++ b/res/values-sr-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Отвори у новој картици у позадини"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Отвори све у новим картицама"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Отварање нових картица иза тренутне"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Желите ли да вратите картице?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Изгледа да је прегледач отказао. Желите ли да вратите картице које сте последње користили?"</string>
</resources>
diff --git a/res/values-sr-xlarge/strings.xml b/res/values-sr-xlarge/strings.xml
index 993e372..b4c6b08 100644
--- a/res/values-sr-xlarge/strings.xml
+++ b/res/values-sr-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Отвори у новој позадинској картици"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Отвори све у новим картицама"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Отварање нових картица иза тренутне картице"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Желите ли да вратите картице?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Изгледа да је прегледач отказао. Желите ли да вратите картице које сте последње користили?"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 77a0145..fd7deaf 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Потврди"</string>
<string name="do_not_save" msgid="6777633870113477714">"Откажи"</string>
<string name="location" msgid="3411848697912600125">"Адреса"</string>
+ <string name="account" msgid="5179824606448077042">"Налог"</string>
<string name="containing_folder" msgid="6771180232953030479">"Додај у"</string>
<string name="new_folder" msgid="7743540149088867917">"Нов директоријум"</string>
<string name="edit_folder" msgid="621817453133656156">"Измени директоријум"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Унесите и сачувајте податке за аутоматско попуњавање поља у веб обрасцима"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Аутоматска пријава на Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Пријављивање на Google сајтове помоћу <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Аутоматско пријављивање је доступно."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Пријављивање као"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Пријави ме"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Сакриј"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Пријављивање није успело."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Унесите податке које желите да аутоматски попуне веб поља када их додирнете."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Пуно име:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Огромно"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Величина текста"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Минимална величина фонта"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Принудно омогући зум"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Да ли треба одбити захтев веб сајта за контролу понашања зума"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Подразумевано зумирај"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Издалека"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"корејски (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Кодирање текста"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Приступачност"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Брзе контроле"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Листањем са леве или десне ивице приступа се брзим контролама и сакривају траке Апликације и URL адресе"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Почетна страница приказује веб странице које најчешће посећујете."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google инстант"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Користите Google инстант са Google претрагом да бисте видели резултате док куцате (то може да повећа употребу података)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Цео екран"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Сакријте статусну траку помоћу режима целог екрана."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Пребацивање верзије"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Пребацивање са верзије сајта за таблете на верзију за рачунаре и обрнуто"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Додирните икону Android-а или лаптопа да бисте са верзије сајта за таблет прешли на верзију за рачунар и обрнуто."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Проблем при повезивању са подацима"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Проблем са датотеком"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Потврда"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Дели"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Нема више доступних картица"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google са Инстантом (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Желите ли да вратите прозоре?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Изгледа да је прегледач отказао. Желите ли да вратите прозоре које сте последње користили?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Да"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Не"</string>
+ <string name="preview" msgid="1470306351083271066">"Преглед:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Локални"</string>
</resources>
diff --git a/res/values-sv-sw600dp/strings.xml b/res/values-sv-sw600dp/strings.xml
index 0015ef5..2236b0c 100644
--- a/res/values-sv-sw600dp/strings.xml
+++ b/res/values-sv-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Öppna i en ny flik i bakgrunden"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Öppna alla i nya flikar"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Öppna nya flikar bakom den aktiva"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Vill du återställa flikarna?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Webbläsaren verkar ha kraschat. Vill du återställa flikarna från förra gången?"</string>
</resources>
diff --git a/res/values-sv-xlarge/strings.xml b/res/values-sv-xlarge/strings.xml
index 0e3cd5b..07b3c5e 100644
--- a/res/values-sv-xlarge/strings.xml
+++ b/res/values-sv-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Öppna i ny flik i bakgrunden"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Öppna alla på en ny flik"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Öppna nya flikar bakom den aktiva"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Vill du återställa flikar?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Webbläsaren verkar ha kraschat. Vill du återställa dina flikar från förra gången?"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 35715ff..ed61277 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Avbryt"</string>
<string name="location" msgid="3411848697912600125">"Adress"</string>
+ <string name="account" msgid="5179824606448077042">"Konto"</string>
<string name="containing_folder" msgid="6771180232953030479">"Lägg till"</string>
<string name="new_folder" msgid="7743540149088867917">"Ny mapp"</string>
<string name="edit_folder" msgid="621817453133656156">"Redigera mapp"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Ange och spara data för automatisk ifyllning av webbformulärfält"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Automatiskt inloggning på Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Loggar in på Google Sites med <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Automatisk inloggning är tillgänglig."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Logga in som"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Logga in"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Dölj"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Misslyckad inloggning."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Ange de data som du vill ska fyllas i automatiskt i webbformulär när du trycker på dem."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Fullständigt namn:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Mycket stor"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Textstorlek"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minsta teckenstorlek"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Tvinga aktivering av zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Om en webbplats begäran om att styra zoomfunktionen ska åsidosättas"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Standardinställning för zoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Lång"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"koreanska (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Textkodning"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Tillgänglighet"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Snabbkontroller"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Svep från vänster eller höger så visas snabbkontrollerna och program- och adressfälten döljs"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"På startsidan visas de webbplatser du besöker oftast."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Använd Google Instant när du söker på Google så får du resultat medan du skriver (detta kan öka dataanvändningen)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Helskärm"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Använd helskärmsläge om du vill dölja statusfältet."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Byt användaragent"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Växla mellan pekdators- och skrivbordsversionen av en webbplats"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Knacka lätt på Android-ikonen eller ikonen för den bärbara datorn när du vill växla mellan pekdators- och skrivbordsversionen av en webbplats."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problem med dataanslutning"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problem med filen"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Bekräfta"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Dela"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Det finnns inga fler flikar"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google med Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Vill du återställa fönster?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Webbläsaren verkar ha kraschat. Vill du återställa dina fönster från förra gången?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Ja"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Nej"</string>
+ <string name="preview" msgid="1470306351083271066">"Förhandsgranska:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokala"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
new file mode 100644
index 0000000..3a41c0a
--- /dev/null
+++ b/res/values-sw/strings.xml
@@ -0,0 +1,621 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 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" msgid="1935869255545976415">" Kivinjari"</string>
+ <string name="choose_upload" msgid="3649366287575002063">"Chagua faili ya kupakia"</string>
+ <!-- no translation found for uploads_disabled (463761197575372994) -->
+ <skip />
+ <string name="new_tab" msgid="4505722538297295141">"Dirisha jipya"</string>
+ <string name="new_incognito_tab" msgid="5821404839654751753">"Dirisha fiche jipya"</string>
+ <string name="active_tabs" msgid="3050623868203544623">"Windows"</string>
+ <string name="tab_bookmarks" msgid="2305793036003473653">"Alamisho"</string>
+ <string name="tab_most_visited" msgid="1077402532455000703">"Zilizotembelewa sana"</string>
+ <string name="tab_history" msgid="1979267558744613746">"Historia"</string>
+ <string name="added_to_bookmarks" msgid="1020224130695956728">"Imeongezwa kwa alamisho"</string>
+ <string name="removed_from_bookmarks" msgid="6063705902028438800">"Imeondolewa kutoka kwa alamisho"</string>
+ <string name="sign_in_to" msgid="5939425800148759165">"Ingia kwa <xliff:g id="HOSTNAME">%s1</xliff:g> \"<xliff:g id="REALM">%s2</xliff:g>\""</string>
+ <!-- no translation found for username (5057566336518215922) -->
+ <skip />
+ <!-- no translation found for password (1177138552305184404) -->
+ <skip />
+ <!-- no translation found for action (183105774472071343) -->
+ <skip />
+ <string name="bookmarks_search" msgid="5229596268214362873">" Kivinjari"</string>
+ <!-- no translation found for cancel (3017274947407233702) -->
+ <skip />
+ <!-- no translation found for ok (1509280796718850364) -->
+ <skip />
+ <string name="title_bar_loading" msgid="7438217780834640678">"Inapakia…"</string>
+ <!-- no translation found for page_info (4048529256302257195) -->
+ <skip />
+ <!-- no translation found for page_info_view (5303490449842635158) -->
+ <skip />
+ <!-- no translation found for page_info_address (2222306609532903254) -->
+ <skip />
+ <!-- no translation found for ssl_warnings_header (79744901983636370) -->
+ <skip />
+ <!-- no translation found for ssl_continue (8031515015829358457) -->
+ <skip />
+ <!-- no translation found for security_warning (6607795404322797541) -->
+ <skip />
+ <!-- no translation found for view_certificate (1472768887529093862) -->
+ <skip />
+ <!-- no translation found for ssl_go_back (4598951822061593819) -->
+ <skip />
+ <!-- no translation found for ssl_untrusted (5369967226521102194) -->
+ <skip />
+ <!-- no translation found for ssl_mismatch (558688832420069896) -->
+ <skip />
+ <!-- no translation found for ssl_expired (5739349389499575559) -->
+ <skip />
+ <!-- no translation found for ssl_not_yet_valid (2893167846212645846) -->
+ <skip />
+ <!-- no translation found for ssl_certificate (5226747157992111668) -->
+ <skip />
+ <!-- no translation found for ssl_certificate_is_valid (7096160815933145579) -->
+ <skip />
+ <!-- no translation found for issued_to (9032338008819841339) -->
+ <skip />
+ <!-- no translation found for common_name (5745530093500062357) -->
+ <skip />
+ <!-- no translation found for org_name (8868889052889991293) -->
+ <skip />
+ <!-- no translation found for org_unit (4489056376307768196) -->
+ <skip />
+ <!-- no translation found for issued_by (6959484326943152487) -->
+ <skip />
+ <!-- no translation found for validity_period (57988851973181309) -->
+ <skip />
+ <!-- no translation found for issued_on (2082890654801808368) -->
+ <skip />
+ <!-- no translation found for expires_on (8061200430557020704) -->
+ <skip />
+ <!-- no translation found for stopping (4839698519340302982) -->
+ <skip />
+ <!-- no translation found for stop (5687251076030630074) -->
+ <skip />
+ <!-- no translation found for reload (8585220783228408062) -->
+ <skip />
+ <!-- no translation found for back (8414603107175713668) -->
+ <skip />
+ <!-- no translation found for forward (4288210890526641577) -->
+ <skip />
+ <!-- no translation found for save (5922311934992468496) -->
+ <skip />
+ <!-- no translation found for do_not_save (6777633870113477714) -->
+ <skip />
+ <string name="location" msgid="3411848697912600125">"Anwani"</string>
+ <!-- no translation found for account (5179824606448077042) -->
+ <skip />
+ <string name="containing_folder" msgid="6771180232953030479">"Ongeza kwa"</string>
+ <string name="new_folder" msgid="7743540149088867917">"Folda mpya"</string>
+ <!-- no translation found for edit_folder (621817453133656156) -->
+ <skip />
+ <!-- no translation found for delete_folder (2046483129024501116) -->
+ <skip />
+ <!-- no translation found for no_subfolders (5880411440592452802) -->
+ <skip />
+ <!-- no translation found for add_to_bookmarks_menu_option (4449323955122214389) -->
+ <skip />
+ <!-- no translation found for add_to_homescreen_menu_option (1461447829242963790) -->
+ <skip />
+ <!-- no translation found for add_to_other_folder_menu_option (5450890093372998187) -->
+ <skip />
+ <string name="name" msgid="5462672162695365387">"Lebo"</string>
+ <!-- no translation found for http (2163722670597250102) -->
+ <skip />
+ <string name="save_to_bookmarks" msgid="6101482434920313244">"Ongeza kwa Alamisho"</string>
+ <string name="bookmark_this_page" msgid="7530739804320811054">"Alamisha ukurasa huu"</string>
+ <string name="remove" msgid="7820112494467011374">"Ondoa"</string>
+ <!-- no translation found for edit_bookmark (5024089053490231905) -->
+ <skip />
+ <string name="create_shortcut_bookmark" msgid="1995095662095484289">"Ongeza njia mkato katika nyumbani"</string>
+ <!-- no translation found for open_bookmark (8473581305759935790) -->
+ <skip />
+ <!-- no translation found for remove_bookmark (8407495852801410891) -->
+ <skip />
+ <string name="remove_from_bookmarks" msgid="4374080666576982775">"Ondoa kutoka kwa alamisho"</string>
+ <!-- no translation found for remove_history_item (5021424935726728618) -->
+ <skip />
+ <string name="set_as_homepage" msgid="4752937379414905560">"Weka ukurasa wa nyumbani"</string>
+ <!-- no translation found for bookmark_saved (2766434679871317557) -->
+ <skip />
+ <string name="bookmark_not_saved" msgid="700600955089376724">"Haiwezi kuhifadhi alamisho."</string>
+ <string name="homepage_set" msgid="8768087280310966395">"Ukurasa wa nyumbani umewekwa."</string>
+ <string name="bookmark_needs_title" msgid="6245900436119218187">"Alamisho lazima iwe na jina."</string>
+ <string name="bookmark_needs_url" msgid="7809876865972755158">"Alamisho lazima iwe na mahali."</string>
+ <!-- no translation found for bookmark_url_not_valid (6719785633980202419) -->
+ <skip />
+ <string name="bookmark_cannot_save_url" msgid="791722768778386941">"URL hii haiwezi kualamishwa."</string>
+ <!-- no translation found for delete_bookmark (2422989994934201992) -->
+ <skip />
+ <!-- no translation found for bookmark_page (6845189305130307274) -->
+ <skip />
+ <!-- no translation found for bookmark_thumbnail_view (3164068314718522138) -->
+ <skip />
+ <!-- no translation found for bookmark_list_view (7848510619500937839) -->
+ <skip />
+ <string name="current_page" msgid="7510129573681663135">"kutoka "</string>
+ <string name="delete_bookmark_warning" msgid="758043186202032205">"Alamisho \"<xliff:g id="BOOKMARK">%s</xliff:g>\" itafutwa."</string>
+ <!-- no translation found for open_all_in_new_window (6514602245828366045) -->
+ <skip />
+ <string name="goto_dot" msgid="3895839050522602723">"Nenda"</string>
+ <string name="incognito_tab" msgid="5419458065370134289">"Fungua kichupo fiche kipya"</string>
+ <string name="select_dot" msgid="6299170761900561967">"Chagua maandishi"</string>
+ <!-- no translation found for tab_picker_title (864478399057782913) -->
+ <skip />
+ <!-- no translation found for tab_picker_remove_tab (630087809802479397) -->
+ <skip />
+ <!-- no translation found for bookmarks (1961279134885867815) -->
+ <skip />
+ <!-- no translation found for shortcut_bookmark (3974876480401135895) -->
+ <skip />
+ <!-- no translation found for history (2451240511251410032) -->
+ <skip />
+ <!-- no translation found for menu_view_download (2124570321712995120) -->
+ <skip />
+ <string name="copy_page_url" msgid="7635062169011319208">"Nakili url ya ukurasa"</string>
+ <!-- no translation found for share_page (593756995297268343) -->
+ <skip />
+ <!-- outdated translation 3934652434001459581 --> <string name="menu_save_webarchive" msgid="2474117375302625691">"Hifadhi kama Jalada la Wavuti"</string>
+ <!-- outdated translation 7045250341467345007 --> <string name="webarchive_saved" msgid="2212053339474523406">"Jalada la wavuti limehifadhiwa."</string>
+ <!-- outdated translation 2880998204746620260 --> <string name="webarchive_failed" msgid="19950914584285713">"Imeshindwa kuhifadhi jalada la wavuti"</string>
+ <!-- no translation found for contextheader_folder_bookmarkcount (353987136645619089) -->
+ <skip />
+ <!-- no translation found for contextheader_folder_empty (974171637803391651) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink (7237961252214188935) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow (992765050093960353) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow_background (5556131402560251639) -->
+ <skip />
+ <!-- no translation found for contextmenu_savelink (5508554930832538184) -->
+ <skip />
+ <!-- no translation found for contextmenu_sharelink (5392275392280130331) -->
+ <skip />
+ <!-- no translation found for contextmenu_copy (398860586635404030) -->
+ <skip />
+ <!-- no translation found for contextmenu_copylink (5153657160294534270) -->
+ <skip />
+ <!-- no translation found for contextmenu_download_image (4243829645180686912) -->
+ <skip />
+ <!-- no translation found for contextmenu_view_image (3870625602053600905) -->
+ <skip />
+ <string name="contextmenu_set_wallpaper" msgid="3691902960115350686">"Weka kama taswira"</string>
+ <!-- no translation found for contextmenu_dial_dot (5856550683415933806) -->
+ <skip />
+ <!-- no translation found for contextmenu_add_contact (3183511922223645716) -->
+ <skip />
+ <!-- no translation found for contextmenu_send_mail (1014513374828775660) -->
+ <skip />
+ <!-- no translation found for contextmenu_map (7471390435434034912) -->
+ <skip />
+ <string name="choosertitle_sharevia" msgid="4600490613341909086">"Shiriki kupitia"</string>
+ <!-- no translation found for clear (7070043081700011461) -->
+ <skip />
+ <!-- no translation found for replace (4843033491070384047) -->
+ <skip />
+ <!-- no translation found for browser_bookmarks_page_bookmarks_text (6787605028726162673) -->
+ <skip />
+ <!-- no translation found for menu_preferences (6709237687234102240) -->
+ <skip />
+ <!-- no translation found for pref_content_title (722227111894838633) -->
+ <skip />
+ <!-- no translation found for pref_content_load_images (2125616852957377561) -->
+ <skip />
+ <string name="pref_content_load_images_summary" msgid="5055874125248398584">"Onyesha picha kwenye kurasa za wavuti"</string>
+ <!-- no translation found for pref_content_block_popups (4158524847764470895) -->
+ <skip />
+ <!-- no translation found for pref_content_javascript (4570972030299516843) -->
+ <skip />
+ <!-- no translation found for pref_content_open_in_background (824123779725118663) -->
+ <skip />
+ <string name="pref_content_plugins" msgid="7231944644794301582">"Wezesha programu-jalizi"</string>
+ <string-array name="pref_content_plugins_choices">
+ <item msgid="6745108155096660725">"Imewashwa kila wakati"</item>
+ <item msgid="2484126708670016519">"Inapohitajika"</item>
+ <item msgid="8547442717307793863">"Zima"</item>
+ </string-array>
+ <string name="pref_content_open_in_background_summary" msgid="1737664075721181678">"Fungua madirisha mapya nyuma ya dirisha la sasa"</string>
+ <!-- no translation found for pref_content_homepage (3324574611613105696) -->
+ <skip />
+ <string name="pref_content_search_engine" msgid="1620101310821644144">"Weka injini tafuti"</string>
+ <string name="pref_content_search_engine_summary" msgid="5162667665858487316">"Teua injini tafuti"</string>
+ <!-- no translation found for pref_set_homepage_to (7196350233061395098) -->
+ <skip />
+ <!-- outdated translation 1493179933653044553 --> <string name="pref_use_current" msgid="1778622474040406672">"Tumia ukurasa wa sasa"</string>
+ <!-- no translation found for pref_use_blank (8503238592551111169) -->
+ <skip />
+ <!-- no translation found for pref_use_default (192587563274735878) -->
+ <skip />
+ <!-- no translation found for pref_content_autofit (8260474534053660809) -->
+ <skip />
+ <string name="pref_content_autofit_summary" msgid="4587831659894879986">"Fomati kurasa za wavuti ili zitoshee skrini"</string>
+ <!-- no translation found for pref_general_title (1946872771219249323) -->
+ <skip />
+ <!-- no translation found for pref_general_sync_title (3138637035975860324) -->
+ <skip />
+ <!-- no translation found for pref_general_autofill_title (547881256865816858) -->
+ <skip />
+ <string name="pref_personal_sync_with_chrome" msgid="1695182180332194033">"Sawazisha kwa Google Chrome"</string>
+ <string name="pref_personal_sync_with_chrome_summary" msgid="7414133931827321055">"Shiriki alamisho na data nyingine kati ya Kivinjari cha Android na Google Chrome"</string>
+ <string name="pref_personal_google_account" msgid="952360133341490071">"Akaunti ya Google"</string>
+ <string name="pref_personal_sync_bookmarks" msgid="59237515966184432">"Sawazisha alamisho"</string>
+ <string name="pref_personal_sync_bookmarks_summary" msgid="4791767605662205482">"Sawazisha alamisho kati ya Kivinjari cha Android na Google Chrome"</string>
+ <string name="pref_personal_start_syncing" msgid="6046972042512655232">"Anza usawazishaji"</string>
+ <string name="pref_personal_account_dialog_title" msgid="1390867119887955530">"Teua akaunti ya Google ya kushiriki nayo"</string>
+ <!-- outdated translation 1174197447388234595 --> <string name="pref_autofill_enabled" msgid="1015751713312396713">"Jaza Fomu Kiotomatiki"</string>
+ <string name="pref_autofill_enabled_summary" msgid="422640696197018914">"Jaza fomu za wavuti kwa kobofya mara moja tu"</string>
+ <!-- outdated translation 1350709161524642663 --> <string name="pref_autofill_profile_editor" msgid="3864116896052437796">"Jaza Mipangilio Kiotomatiki"</string>
+ <!-- outdated translation 6748434431641768870 --> <string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Weka na udhibiti data ya fomu zilizojazwa kiotomatiki"</string>
+ <!-- no translation found for pref_autologin_title (2362827272595366379) -->
+ <skip />
+ <!-- no translation found for pref_autologin_progress (8333244467048833461) -->
+ <skip />
+ <!-- no translation found for autologin_bar_text (3684581827167173371) -->
+ <skip />
+ <!-- no translation found for autologin_bar_login_text (7052816600314556734) -->
+ <skip />
+ <!-- no translation found for autologin_bar_hide_text (3629355974385859580) -->
+ <skip />
+ <!-- no translation found for autologin_bar_error (5132514366023044839) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_heading (8392952553626722083) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_name (8566130291459685955) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_email_address (7967585896612797173) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_company_name (2813443159949210417) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1 (836433242509243081) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1_hint (5965659598509327172) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2 (8194745202893822479) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2_hint (2048330295853546405) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_city (4193225955409148508) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_state (8549739922338171458) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_zip_code (283668573295656671) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_country (7234470301239156656) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number (4938852821413729276) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number_invalid (7166394872369167580) -->
+ <skip />
+ <string name="autofill_profile_editor_save_profile" msgid="8349915287435262888">"Hifadhi maelezo mafupi"</string>
+ <!-- no translation found for autofill_profile_successful_save (6834102203944938409) -->
+ <skip />
+ <!-- no translation found for autofill_profile_successful_delete (2421442112954362732) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_delete_profile (2754563301088418752) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_message (6605682320156223114) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_negative_toast (6990737008936188620) -->
+ <skip />
+ <!-- no translation found for disable_autofill (8305901059849400354) -->
+ <skip />
+ <!-- no translation found for pref_privacy_security_title (3480313968942160914) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cache (3380316479925886998) -->
+ <skip />
+ <string name="pref_privacy_clear_cache_summary" msgid="2216463577207991454">"Futa maudhui na hifadhidata zilizoakibishwa kwenye simu"</string>
+ <string name="pref_privacy_clear_cache_dlg" msgid="5541011591300753881">"Maudhui na hifadhidata zilizoakibishwa kwenye simu zitafutwa."</string>
+ <!-- no translation found for pref_privacy_cookies_title (6763274282214830526) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cookies (3095583579133780331) -->
+ <skip />
+ <string name="pref_privacy_clear_cookies_summary" msgid="6962742063990677520">"Futa kuki zote za kivinjari"</string>
+ <string name="pref_privacy_clear_cookies_dlg" msgid="552855688091432682">"Kuki zote zitafutwa."</string>
+ <!-- no translation found for pref_privacy_clear_history (8723795508825198477) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_history_summary (6868501330708940734) -->
+ <skip />
+ <string name="pref_privacy_clear_history_dlg" msgid="544903007914753853">"Historia ya uabiri wa kivinjari itafutwa."</string>
+ <!-- no translation found for pref_privacy_formdata_title (6549813837982050424) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data (4232668196344383987) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data_summary (1790390894719517167) -->
+ <skip />
+ <string name="pref_privacy_clear_form_data_dlg" msgid="4443621086781197928">"Data yote iliyohifadhiwa ya fomu itafutwa."</string>
+ <!-- no translation found for pref_privacy_clear_passwords (4750234112289277480) -->
+ <skip />
+ <string name="pref_privacy_clear_passwords_summary" msgid="8856782718942903335">"Futa manenosiri yote yaliyohifadhiwa"</string>
+ <string name="pref_privacy_clear_passwords_dlg" msgid="2083869328824248255">"Manenosiri yote yaliyohifadhiwa yatafutwa."</string>
+ <!-- no translation found for pref_privacy_location_title (7458378016606081067) -->
+ <skip />
+ <string name="pref_privacy_enable_geolocation" msgid="1395040170290765686">"Wezesha mahali"</string>
+ <string name="pref_privacy_enable_geolocation_summary" msgid="8437020934664306205">"Ruhusu tovuti kuomba ufikiaji mahali pako"</string>
+ <string name="pref_privacy_clear_geolocation_access" msgid="6649680770030042980">"Futa ufikiaji mahali"</string>
+ <string name="pref_privacy_clear_geolocation_access_summary" msgid="7750143359497314679">"Futa ufikiaji mahali kwa tovuti zote"</string>
+ <string name="pref_privacy_clear_geolocation_access_dlg" msgid="7327063124488827244">"Futa ufikiaji mahali kwa tovuti zote"</string>
+ <!-- no translation found for pref_security_passwords_title (5734190542383756711) -->
+ <skip />
+ <!-- no translation found for pref_security_remember_passwords (6492957683454529549) -->
+ <skip />
+ <string name="pref_security_remember_passwords_summary" msgid="256388703356349137">"Hifadhi majina ya mtumiaji na manenosiri ya tovuti"</string>
+ <!-- no translation found for pref_security_save_form_data (1213669802810198893) -->
+ <skip />
+ <!-- no translation found for pref_security_save_form_data_summary (4994074685153708026) -->
+ <skip />
+ <!-- no translation found for pref_security_show_security_warning (8901135676266754559) -->
+ <skip />
+ <string name="pref_security_show_security_warning_summary" msgid="8968906112720511704">"Onyesha onyo kama kuna tatizo la usalama wa tovuti"</string>
+ <!-- no translation found for pref_security_accept_cookies (3201367661925047989) -->
+ <skip />
+ <string name="pref_security_accept_cookies_summary" msgid="1465118934875026920">"Ruhusu tovuti kuhifadhi na kusoma data ya \"kuki\"."</string>
+ <!-- no translation found for pref_text_size (3827031324346612208) -->
+ <skip />
+ <string-array name="pref_text_size_choices">
+ <item msgid="4952686548944739548">"Dogo sana"</item>
+ <item msgid="1950030433642671460">"Ndogo"</item>
+ <item msgid="4338347520133294584">"Kawaida"</item>
+ <item msgid="5043128215356351184">"Kubwa"</item>
+ <item msgid="7201512237890458902">"Kubwa mno"</item>
+ </string-array>
+ <!-- no translation found for pref_text_size_dialogtitle (3625388833512647865) -->
+ <skip />
+ <!-- no translation found for pref_min_font_size (8811125835817449131) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable (5641500562399892621) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable_summary (4431962409438162448) -->
+ <skip />
+ <string name="pref_default_zoom" msgid="8076142259097187395">"Kuza chaguo-msingi"</string>
+ <string-array name="pref_default_zoom_choices">
+ <item msgid="549583171195154919">"Mbali"</item>
+ <item msgid="5619034257768161024">"Wastani"</item>
+ <item msgid="3840999588443167001">"Funga"</item>
+ </string-array>
+ <string name="pref_default_zoom_dialogtitle" msgid="6095974367125109021">"Kuza chaguo-msingi"</string>
+ <string name="pref_content_load_page" msgid="2219810141690955452">"Fungua kurasa katika muhtasari."</string>
+ <string name="pref_content_load_page_summary" msgid="8792093504054149369">"Onyesha muhtasari wa kurasa mpya zilizofunguliwa"</string>
+ <!-- no translation found for pref_extras_title (7075456173747370647) -->
+ <skip />
+ <string name="pref_extras_website_settings" msgid="67866640052455549">"Mipangilio ya tovuti"</string>
+ <string name="pref_extras_website_settings_summary" msgid="1656771443223494406">"Mipangilio mahiri kwa wavuti mahsusi"</string>
+ <!-- no translation found for pref_extras_reset_default_title (3579760449455761762) -->
+ <skip />
+ <!-- no translation found for pref_extras_reset_default (8904000515846202110) -->
+ <skip />
+ <string name="pref_extras_reset_default_summary" msgid="4247870778270414501">"Rejesha mipangilio chaguo-msingi"</string>
+ <string name="pref_extras_reset_default_dlg" msgid="6640261575874704022">"Mipangilio zitarejeshwa kwa thamani chaguo-msingi"</string>
+ <!-- no translation found for pref_extras_reset_default_dlg_title (2250334970728938936) -->
+ <skip />
+ <!-- no translation found for pref_development_title (3263854204533056480) -->
+ <skip />
+ <string name="pref_default_text_encoding" msgid="5742965543955558478">"Usimbaji maandishi"</string>
+ <string-array name="pref_default_text_encoding_choices">
+ <item msgid="7275223955790513818">"Kilatini-1 (ISO-8859-1)"</item>
+ <item msgid="2456597866837587140">"Msimbosare (UTF-8)"</item>
+ <item msgid="6122474363777211732">"Kichina (GBK)"</item>
+ <item msgid="373372275931607040">"Kichina (Big5)"</item>
+ <item msgid="891615911084608570">"Kijapani (ISO-2022-JP)"</item>
+ <item msgid="5589150448475151241">"Kijapani (SHIFT_JIS)"</item>
+ <item msgid="7356792686950371843">"Kijapani (EUC-JP)"</item>
+ <item msgid="2193955365569270096">"Kikorea (EUC-KR)"</item>
+ </string-array>
+ <string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Usimbaji maandishi"</string>
+ <!-- no translation found for pref_accessibility_title (5127836981587423215) -->
+ <skip />
+ <!-- no translation found for pref_lab_title (5571091610359629423) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls (3267606522082281367) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls_summary (1564546156544675707) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage (7597766876952506909) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage_summary (4132511544800457513) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search (1119176077760723740) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search_summary (839320474961917522) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen (8173609016657987973) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen_summary (6853711692160711419) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher (9063310468293037499) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher_summary (1782363693543953474) -->
+ <skip />
+ <!-- no translation found for help_useragent_switcher (123586256526014375) -->
+ <skip />
+ <!-- no translation found for browserFrameNetworkErrorLabel (126892350904924893) -->
+ <skip />
+ <!-- no translation found for browserFrameFileErrorLabel (8063691502792670367) -->
+ <skip />
+ <!-- no translation found for browserFrameFormResubmitLabel (2685923472682180360) -->
+ <skip />
+ <string name="browserFrameFormResubmitMessage" msgid="2752182215695632138">"Ukurasa unaojaribu kuangalia una data ambayo imewasilishwa tayari (\"POSTDATA\"). Ukituma data tena, kitendo chochote ambacho fomu kwenye ukurasa ilitekeleza (kama vile utafutaji au ununuzi kwenye wavuti) kitarudiwa."</string>
+ <!-- no translation found for loadSuspendedTitle (675991625288706944) -->
+ <skip />
+ <string name="loadSuspended" msgid="3133656588880851273">"Kivinjari hakiwezi kupakia ukurasa huu kwa sababu hakuna muunganisho wa mtandao."</string>
+ <!-- no translation found for clear_history (5998307092715979619) -->
+ <skip />
+ <string name="browser_history" msgid="1038987118290272525">"Kurasa zilizotembelewa hivi karibuni"</string>
+ <!-- no translation found for empty_history (8738772352308207274) -->
+ <skip />
+ <string name="add_new_bookmark" msgid="8086367791400349049">"Ongeza alamisho..."</string>
+ <string name="add_bookmark_short" msgid="3783984330998103735">"Ongeza"</string>
+ <string name="search_hint" msgid="4647356319916631820">"Tafuta au chapa URL"</string>
+ <!-- no translation found for search_button_text (5235226933877634410) -->
+ <skip />
+ <string name="search_settings_description" msgid="1422401062529014107">"Alamisho na historia ya wavuti"</string>
+ <!-- no translation found for attention (3473639060042811244) -->
+ <skip />
+ <string name="popup_window_attempt" msgid="2673111696288657989">"Tovuti hii inajaribu kufungua dirisha ibukizi."</string>
+ <!-- no translation found for allow (1157313689171991335) -->
+ <skip />
+ <!-- no translation found for block (9172175889884707800) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_title (5175503564948906442) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_message (1398571800233959583) -->
+ <skip />
+ <!-- no translation found for too_many_subwindows_dialog_title (3805453941587725944) -->
+ <skip />
+ <string name="too_many_subwindows_dialog_message" msgid="5827289829907966657">"Haikuweza kufungua dirisha jipya la ibukizi kwa sababu ni moja tu unaoweza kufunguliwa kwa wakati mmoja."</string>
+ <!-- no translation found for download_title (2122874021047565594) -->
+ <skip />
+ <!-- no translation found for download_unknown_filename (4013465542563652175) -->
+ <skip />
+ <!-- no translation found for download_menu_open (4888327480367757513) -->
+ <skip />
+ <!-- no translation found for download_menu_clear (6264454531553418124) -->
+ <skip />
+ <string name="download_menu_delete" msgid="8815502136393894148">"Futa"</string>
+ <!-- no translation found for download_menu_cancel (2545333007601851574) -->
+ <skip />
+ <!-- no translation found for download_menu_cancel_all (2136550823151999166) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_title (8909108500262799748) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_msg (6285389170052357797) -->
+ <skip />
+ <string name="download_delete_file" msgid="5330036497843073249">"Faili itafutwa"</string>
+ <!-- no translation found for download_file_error_dlg_title (2693630283595384874) -->
+ <skip />
+ <string name="download_file_error_dlg_msg" msgid="5156405410324072471">"<xliff:g id="FILENAME">%s</xliff:g> haikuweza kupakuliwa."\n"Futa vitu kadhaa upate nafasi kwenye simu yako na ujaribu tena."</string>
+ <!-- no translation found for download_failed_generic_dlg_title (6106781095337833391) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (56777245081568508) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (605904452159416792) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (3144652102051031721) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (2616399456116301518) -->
+ <skip />
+ <!-- outdated translation 6877712666046917741 --> <string name="download_sdcard_busy_dlg_title" product="nosdcard" msgid="8081445664689818973">"Kadi ya SD haipatikani"</string>
+ <string name="download_sdcard_busy_dlg_title" product="default" msgid="6877712666046917741">"Kadi ya SD haipatikani"</string>
+ <!-- outdated translation 3473883538192835204 --> <string name="download_sdcard_busy_dlg_msg" product="nosdcard" msgid="3979329954835690147">"Kadi ya SD ina shughuli. Kuruhusu vipakuzi, chagua \"Zima hifadhi ya USB\" katika arifa."</string>
+ <string name="download_sdcard_busy_dlg_msg" product="default" msgid="3473883538192835204">"Kadi ya SD ina shughuli. Kuruhusu vipakuzi, chagua \"Zima hifadhi ya USB\" katika arifa."</string>
+ <!-- no translation found for cannot_download (8150552478556798780) -->
+ <skip />
+ <string name="download_no_application_title" msgid="1286056729168874295">"Haiwezi kufungua faili"</string>
+ <!-- no translation found for retry (1835923075542266721) -->
+ <skip />
+ <!-- no translation found for no_downloads (3947445710685021498) -->
+ <skip />
+ <!-- no translation found for download_error (413496839831257187) -->
+ <skip />
+ <!-- no translation found for download_success (2279041638155595203) -->
+ <skip />
+ <!-- no translation found for download_running (2622942231322015059) -->
+ <skip />
+ <!-- no translation found for download_pending (2599683668575349559) -->
+ <skip />
+ <!-- no translation found for download_pending_network (6548714525679461053) -->
+ <skip />
+ <!-- no translation found for download_running_paused (6418029352085656495) -->
+ <skip />
+ <!-- no translation found for download_canceled (6057083743144492515) -->
+ <skip />
+ <string name="download_not_acceptable" msgid="313769696131563652">"Haiwezi kupakua. Maudhui hayahimiliwi kwenye simu hii."</string>
+ <!-- no translation found for download_file_error (1206648050615176113) -->
+ <skip />
+ <!-- no translation found for download_length_required (9038605488460437406) -->
+ <skip />
+ <!-- no translation found for download_precondition_failed (8327584102874295580) -->
+ <skip />
+ <string name="search_the_web" msgid="6046130189241962337">"Tafuta wavuti"</string>
+ <string name="webstorage_outofspace_notification_title" msgid="1160474608059771788">"Hifadhi ya kivinjari imejaa"</string>
+ <string name="webstorage_outofspace_notification_text" msgid="7341075135051829692">"Bofya ili kupata nafasi."</string>
+ <string name="webstorage_clear_data_title" msgid="689484577124333977">"Futa data iliyohifadhiwa"</string>
+ <string name="webstorage_clear_data_dialog_title" msgid="345457466368974706">"Futa data iliyohifadhiwa"</string>
+ <string name="webstorage_clear_data_dialog_message" msgid="6678281256970470125">"Data yote iliyohifadhiwa na tovuti hii itafutwa"</string>
+ <string name="webstorage_clear_data_dialog_ok_button" msgid="2516563534211898636">"Futa zote"</string>
+ <string name="webstorage_clear_data_dialog_cancel_button" msgid="2028867751958942762">"Ghairi"</string>
+ <string name="webstorage_origin_summary_mb_stored" msgid="1985885826292236210">"MB imehifadhiwa kwenye simu yako"</string>
+ <string name="loading_video" msgid="4887871585216091096">"Inapakia video"</string>
+ <string name="geolocation_permissions_prompt_message" msgid="356796102004052471">"<xliff:g id="WEBSITE_ORIGIN">%s</xliff:g> anataka kujua mahali pako"</string>
+ <string name="geolocation_permissions_prompt_share" msgid="9084486342048347976">"Shiriki mahali"</string>
+ <string name="geolocation_permissions_prompt_dont_share" msgid="6303025160237860300">"Kataa"</string>
+ <string name="geolocation_permissions_prompt_remember" msgid="3118526300707348308">"Kumbuka mapendeleo"</string>
+ <string name="geolocation_permissions_prompt_toast_allowed" msgid="987286072035125498">"Tovuti hii inaweza kufikia mahali pako. Badilisha hii katika Mipangilio -> Mipangilio ya tovuti"</string>
+ <string name="geolocation_permissions_prompt_toast_disallowed" msgid="7695100950212692515">"Tovuti hii haiwezi kufikia mahali pako. Badilisha hili katika Mipangilio -> Mipangilio ya wavuti"</string>
+ <string name="geolocation_settings_page_title" msgid="1745477985097536528">"Futa ufikiaji mahali"</string>
+ <string name="geolocation_settings_page_summary_allowed" msgid="9180251524290811398">"Tovuti hii kwa sasa inaweza kufikia mahali ulipo"</string>
+ <string name="geolocation_settings_page_summary_not_allowed" msgid="4589649082203102544">"Tovuti hii kwa sasa haiwezi kufikia mahali ulipo"</string>
+ <string name="geolocation_settings_page_dialog_title" msgid="1549842043381347668">"Futa ufikiaji mahali"</string>
+ <string name="geolocation_settings_page_dialog_message" msgid="7586671987576403993">"Uwezo wa tovuti hii kufikia mahali ulipo utafutwa."</string>
+ <string name="geolocation_settings_page_dialog_ok_button" msgid="4789434178048077287">"Futa ufikiaji"</string>
+ <string name="geolocation_settings_page_dialog_cancel_button" msgid="7941036504673409747">"Ghairi"</string>
+ <string name="website_settings_clear_all" msgid="8739804325997655980">"Futa zote"</string>
+ <string name="website_settings_clear_all_dialog_title" msgid="7791826325122461718">"Futa mipangilio yote ya tovuti?"</string>
+ <string name="website_settings_clear_all_dialog_message" msgid="6150502090601476333">"Data ya tovuti zote na vibali vya mahali vitafutwa."</string>
+ <string name="website_settings_clear_all_dialog_ok_button" msgid="6401582240627669431">"Futa data yote"</string>
+ <string name="website_settings_clear_all_dialog_cancel_button" msgid="1896757051856611674">"Ghairi"</string>
+ <string name="progress_dialog_setting_wallpaper" msgid="4871900779338536674">"Inapangilia taswira..."</string>
+ <string name="defaultBookmarksUpButton" msgid="2303951020715704735">"Alamisho"</string>
+ <string name="empty_bookmarks_folder" msgid="7843361614634930942">"Hakuna alamisho"</string>
+ <string name="rlz_access_point" msgid="7165847807377650632">"Y1"</string>
+ <!-- no translation found for account_chooser_dialog_title (3314204833188808194) -->
+ <!-- no translation found for account_chooser_dialog_title (4833571985009544332) -->
+ <skip />
+ <string name="import_bookmarks_dialog_title" msgid="3325557652271172128">"Sawazisha kwa akaunti ya Google"</string>
+ <!-- outdated translation 2187665745413495303 --> <string name="import_bookmarks_dialog_description" msgid="1942452375564381488">"Alamisho zako za Android hazihusishwi na akaunti ya Google"</string>
+ <!-- no translation found for import_bookmarks_dialog_select_add_account (3102882579089291099) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_delete_select_account (5192284761080626386) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_delete (8854001080444749211) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_add (5433677293195372675) -->
+ <skip />
+ <!-- outdated translation 8105572409059113340 --> <string name="import_bookmarks_dialog_remove" msgid="5984607822851800902">"Ondoa alamisho zako za Android"</string>
+ <!-- no translation found for import_bookmarks_wizard_next (7578143961884352676) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_previous (8551440353688257031) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_cancel (4936061122806506634) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_done (1446247092194489191) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_add (7552306756868669353) -->
+ <skip />
+ <string name="import_bookmarks_dialog_import" msgid="6933613853573899218">"Ongeza alamamisho zako za Android kwa alamisho za <xliff:g id="GOOGLE_ACCOUNT">%s</xliff:g>"</string>
+ <!-- no translation found for menu_share_url (5851814357333739700) -->
+ <skip />
+ <!-- no translation found for max_tabs_warning (4122034303809457570) -->
+ <skip />
+ <!-- no translation found for instant_search_label (8769284297650716935) -->
+ <skip />
+ <!-- no translation found for recover_title (8095611702406163360) -->
+ <skip />
+ <!-- no translation found for recover_prompt (5526783279696786755) -->
+ <skip />
+ <!-- no translation found for recover_yes (5837971910598069183) -->
+ <skip />
+ <!-- no translation found for recover_no (3121030267940592611) -->
+ <skip />
+ <!-- no translation found for preview (1470306351083271066) -->
+ <skip />
+ <!-- no translation found for local_bookmarks (533816851415228520) -->
+ <skip />
+</resources>
diff --git a/res/values-sw600dp-port/dimensions.xml b/res/values-sw600dp-port/dimensions.xml
index 7c0d447..3ba38fe 100644
--- a/res/values-sw600dp-port/dimensions.xml
+++ b/res/values-sw600dp-port/dimensions.xml
@@ -16,4 +16,5 @@
<dimen name="widgetVerticalSpacing">6dip</dimen>
<dimen name="combo_paddingLeftRight">16dip</dimen>
<dimen name="combo_horizontalSpacing">8dip</dimen>
+ <dimen name="combo_rowPadding">10dip</dimen>
</resources>
diff --git a/res/values-sw600dp-w1200dp/dimensions.xml b/res/values-sw600dp-w1200dp/dimensions.xml
deleted file mode 100644
index de9616b..0000000
--- a/res/values-sw600dp-w1200dp/dimensions.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2011 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <dimen name="combo_paddingLeftRight">134dip</dimen>
- <dimen name="combo_horizontalSpacing">20dip</dimen>
-</resources>
diff --git a/res/values-sw600dp/dimensions.xml b/res/values-sw600dp/dimensions.xml
index cbb0ba9..82fc37e 100644
--- a/res/values-sw600dp/dimensions.xml
+++ b/res/values-sw600dp/dimensions.xml
@@ -25,6 +25,15 @@
<dimen name="mv_border_width">3dp</dimen>
<!-- For the combined Bookmarks History view -->
<dimen name="combo_paddingTop">50dip</dimen>
- <dimen name="combo_paddingLeftRight">32dip</dimen>
+ <dimen name="combo_paddingLeftRight">134dip</dimen>
<dimen name="combo_horizontalSpacing">8dip</dimen>
+ <dimen name="combo_rowPadding">10dip</dimen>
+ <dimen name="qc_radius_start">50dip</dimen>
+ <dimen name="qc_radius_increment">70dip</dimen>
+ <dimen name="qc_slop">15dip</dimen>
+ <dimen name="qc_touch_offset">15dip</dimen>
+ <dimen name="qc_tab_title_height">30dip</dimen>
+ <dimen name="qc_thumb_width">240dip</dimen>
+ <dimen name="qc_thumb_height">160dip</dimen>
+ <dimen name="qc_item_size">48dip</dimen>
</resources>
diff --git a/res/values-sw600dp/strings.xml b/res/values-sw600dp/strings.xml
index 92646a4..d715c1b 100644
--- a/res/values-sw600dp/strings.xml
+++ b/res/values-sw600dp/strings.xml
@@ -32,4 +32,8 @@
<string name="open_all_in_new_window">Open all in new tabs</string>
<!-- Settings summary CHAR LIMIT=50]-->
<string name="pref_content_open_in_background_summary">Open new tabs behind the current one</string>
+ <!-- Recover tabs after a crash dialog title [CHAR LIMIT=32] -->
+ <string name="recover_title">Restore tabs?</string>
+ <!-- Recover tabs after a crash dialog prompt [CHAR LIMIT=none] -->
+ <string name="recover_prompt">Browser appears to have crashed. Would you like to restore your tabs from last time?</string>
</resources>
diff --git a/res/values-th-sw600dp/strings.xml b/res/values-th-sw600dp/strings.xml
index d96f82a..424af46 100644
--- a/res/values-th-sw600dp/strings.xml
+++ b/res/values-th-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"เปิดในแท็บพื้นหลังใหม่"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"เปิดทั้งหมดในแท็บใหม่"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"เปิดแท็บใหม่หลังแท็บปัจจุบัน"</string>
+ <string name="recover_title" msgid="1558775426269800998">"คืนค่าแท็บหรือไม่"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"ดูเหมือนว่าจะเกิดข้อขัดข้องกับเบราว์เซอร์ คุณต้องการคืนค่าแท็บจากครั้งที่แล้วหรือไม่"</string>
</resources>
diff --git a/res/values-th-xlarge/strings.xml b/res/values-th-xlarge/strings.xml
index 7eb654b..9047f27 100644
--- a/res/values-th-xlarge/strings.xml
+++ b/res/values-th-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"เปิดในแท็บพื้นหลังใหม่"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"เปิดทั้งหมดในแท็บใหม่"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"เปิดแท็บใหม่หลังแท็บปัจจุบัน"</string>
+ <string name="recover_title" msgid="7754049918641251703">"กู้แท็บคืนหรือไม่"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"ดูเหมือนว่าจะเกิดข้อขัดข้องกับเบราว์เซอร์ คุณต้องการคืนค่าแท็บจากครั้งที่แล้วหรือไม่"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 97e9d23..73e9bdb 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"ตกลง"</string>
<string name="do_not_save" msgid="6777633870113477714">"ยกเลิก"</string>
<string name="location" msgid="3411848697912600125">"ที่อยู่"</string>
+ <string name="account" msgid="5179824606448077042">"บัญชี"</string>
<string name="containing_folder" msgid="6771180232953030479">"เพิ่มใน"</string>
<string name="new_folder" msgid="7743540149088867917">"โฟลเดอร์ใหม่"</string>
<string name="edit_folder" msgid="621817453133656156">"แก้ไขโฟลเดอร์"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"ป้อนและบันทึกข้อมูลสำหรับการป้อนฟิลด์ของเว็บฟอร์มอัตโนมัติ"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"ลงชื่อเข้าใช้ Google อัตโนมัติ"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"ลงชื่อเข้าใช้ Google Sites โดยใช้ <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"การลงชื่อเข้าใช้อัตโนมัติพร้อมใช้งาน"</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"ลงชื่อเข้าใช้ในฐานะ"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"ลงชื่อเข้าใช้"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"ซ่อน"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"ลงชื่อเข้าใช้ล้มเหลว"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"ป้อนข้อมูลที่คุณต้องการให้ป้อนอัตโนมัติในเว็บฟิลด์เมื่อคุณแตะฟิลด์เหล่านั้น"</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"ชื่อเต็ม:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"ใหญ่มาก"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"ขนาดข้อความ"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"ขนาดแบบอักษรขั้นต่ำ"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"บังคับเปิดใช้งานการขยาย"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"แทนที่คำขอควบคุมการขยายของเว็บไซต์หรือไม่"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"การซูมเริ่มต้น"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"ไกล"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"เกาหลี (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"การเข้ารหัสข้อความ"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"การเข้าถึง"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"การควบคุมอย่างรวดเร็ว"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"กวาดหัวแม่มือจากซ้ายหรือขวาเพื่อการควบคุมที่รวดเร็วและซ่อนแอปพลิเคชันและแถบ URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"หน้าแรกของคุณจะแสดงหน้าเว็บที่เข้าชมบ่อยที่สุด"</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google ค้นหาทันใจ"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"ใช้ Google ค้นหาทันใจเมื่อคุณใช้ Google Search เพื่อแสดงผลการค้นหาในขณะที่คุณพิมพ์ (ซึ่งสามารถเพิ่มการใช้งานข้อมูล)"</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"เต็มหน้าจอ"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"ใช้โหมดเต็มหน้าจอเพื่อซ่อนแถบสถานะ"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"การสลับตัวแทนผู้ใช้"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"สลับระหว่างไซต์รุ่นแท็บเล็ตและรุ่นเดสก์ท็อป"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"แตะที่ไอคอน Android หรือแลปท็อปเพื่อสลับระหว่างไซต์รุ่นแท็บเล็ตและรุ่นเดสก์ท็อป"</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"ปัญหาการเชื่อมต่อข้อมูล"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"ปัญหาเกี่ยวกับไฟล์"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"ยืนยัน"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"แบ่งปัน"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"ไม่สามารถใช้แท็บเพิ่มได้"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google พร้อมการค้นหาทันใจ (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"กู้หน้าต่างคืนหรือไม่"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"ดูเหมือนว่าจะเกิดข้อขัดข้องกับเบราว์เซอร์ คุณต้องการคืนค่าหน้าต่างจากครั้งที่แล้วหรือไม่"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"ใช่"</string>
+ <string name="recover_no" msgid="3121030267940592611">"ไม่"</string>
+ <string name="preview" msgid="1470306351083271066">"ดูตัวอย่าง:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"ในตัวเครื่อง"</string>
</resources>
diff --git a/res/values-tl-sw600dp/strings.xml b/res/values-tl-sw600dp/strings.xml
index 7c8dd5e..3b0c0c5 100644
--- a/res/values-tl-sw600dp/strings.xml
+++ b/res/values-tl-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Buksan sa tab na bagong background"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Buksan ang lahat sa mga bagong tab"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Buksan ang bagong tab sa likod ng kasalukuyang tab"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Ibalik ang mga tab?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Lumilitaw na nag-crash ang browser. Gusto mo bang ibalik ang iyong mga tab sa dati?"</string>
</resources>
diff --git a/res/values-tl-xlarge/strings.xml b/res/values-tl-xlarge/strings.xml
index 069d6eb..fbbfb73 100644
--- a/res/values-tl-xlarge/strings.xml
+++ b/res/values-tl-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Buksan sa bagong tab na background"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Buksan sa lahat ng mga bagong tab"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Buksan ang mga bagong tab sa likod ng kasalukuyan"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Ibalik ang mga tab?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Mukhang nag-crash ang browser. Gusto mo bang ibalik ang iyong mga tab mula sa nakaraan?"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index cf791c4..2e1a3e2 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Kanselahin"</string>
<string name="location" msgid="3411848697912600125">"Address"</string>
+ <string name="account" msgid="5179824606448077042">"Account"</string>
<string name="containing_folder" msgid="6771180232953030479">"Idagdag sa"</string>
<string name="new_folder" msgid="7743540149088867917">"Bagong folder"</string>
<string name="edit_folder" msgid="621817453133656156">"I-edit ang folder"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Ilagay at i-save ang data para sa mga field ng form ng web sa pag-auto-fill"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Awtomatiko pag-sign in sa Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Pag-sign in sa mga site ng Google gamit ang <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Available ang awtomatikong pag-sign in."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Mag-sign in bilang"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Mag-login"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Itago"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Nabigo ang pag-login."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Ilagay ang data na gusto mong i-auto-fill sa mga field ng web kapag hinawakan mo ang mga ito."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Buong pangalan:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Malaki"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Laki ng teksto"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimum na laki ng font"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Pwersahing paganahin ang zoom"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Override o hindi hiling site na ikontrol galaw ng zoom"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Default zoom"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Malayo"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korean (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Pag-encode ng teksto"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Pagiging Naa-access"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Mga Lab"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Mga mabilis na pagkontrol"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"I-swipe thumb sa kaliwa o kanan gilid para access bilis kontrol at itago Application at URL bar"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Ipinapakita ng iyong homepage ang iyong pinaka-nabibisitang mga webpage."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Gamit Google Instant pag gumamit ka Google Search, para magpakita resulta habang type ka (mapataas nito paggamit data)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Fullscreen"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Gamitin ang mode na fullscreen upang itago ang status bar."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent Switcher"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Mag-toggle sa pagitan ng mga bersyon ng tablet at desktop ng isang site"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Tapikin ang Android o laptop na icon upang mag-toggle sa pagitan ng mga bersyon ng tablet at desktop ng isang site."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Problema sa pagkakakonekta ng data"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Problema sa file"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Kumpirmahin"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Ibahagi"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Wala nang available na mga tab"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google na mayroong Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Ibalik ang windows?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Mukhang nag-crash ang browser. Gusto mo bang ibalik ang iyong windows mula sa nakaraan?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Oo"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Hindi"</string>
+ <string name="preview" msgid="1470306351083271066">"Preview:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Lokal"</string>
</resources>
diff --git a/res/values-tr-sw600dp/strings.xml b/res/values-tr-sw600dp/strings.xml
index 95605bb..5f62065 100644
--- a/res/values-tr-sw600dp/strings.xml
+++ b/res/values-tr-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Yeni arka plan sekmesinde aç"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Tümünü yeni sekmelerde aç"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Yeni sekmeleri mevcut sekmenin arkasında aç"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Sekmeler geri yüklensin mi?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Tarayıcı kilitlenmiş görünüyor. Son kullandığınız sekmelerin geri yüklenmesini ister misiniz?"</string>
</resources>
diff --git a/res/values-tr-xlarge/strings.xml b/res/values-tr-xlarge/strings.xml
index ad88d26..9836e2a 100644
--- a/res/values-tr-xlarge/strings.xml
+++ b/res/values-tr-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Yeni arka plan sekmesinde aç"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Tümünü yeni sekmelerde aç"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Yeni sekmeleri geçerli sekmenin arkasında aç"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Sekmeler geri yüklensin mi?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Tarayıcı kilitlenmiş görünüyor. Son kullandığınız sekmelerin geri yüklenmesini ister misiniz?"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 9896e0c..0990eaa 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"Tamam"</string>
<string name="do_not_save" msgid="6777633870113477714">"İptal"</string>
<string name="location" msgid="3411848697912600125">"Adres"</string>
+ <string name="account" msgid="5179824606448077042">"Hesap"</string>
<string name="containing_folder" msgid="6771180232953030479">"Şu klasöre ekle"</string>
<string name="new_folder" msgid="7743540149088867917">"Yeni klasör"</string>
<string name="edit_folder" msgid="621817453133656156">"Klasörü düzenle"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Web formu alanlarının otomatik olarak doldurulması için verileri girin ve kaydedin"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Otomatik Google oturumu açma"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"<xliff:g id="ID_1">%s</xliff:g> kullanılarak Google sitelerinde oturum açılıyor"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Otomatik oturum açma kullanılabilir."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Farklı kullanıcı olarak oturum aç"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Giriş yap"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Gizle"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Giriş yapılamadı."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Dokunduğunuz web alanlarına otomatik olarak doldurulmasını istediğiniz verileri girin."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Tam ad:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Çok büyük"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Metin boyutu"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Minimum yazı tipi boyutu"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Yakınlştrmyı etknlştrmye zorla"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Sitenin yakınlaştırmayı kontrol isteğinin geçersiz kılınıp kılınmayacağı"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Varsayılan zum"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Uzak"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Korece (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Metin kodlama"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Erişilebilirlik"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Labs"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Hızlı denetimler"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Hızlı dentmlr erşmk, Uyg ve URL çubklr gizlmk için başprmğnzı sol veya sağ kenrdn hızlc kaydrn"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Ana sayfanızda en sık ziyaret edilen web sayfaları görüntülenir."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Anında Arama"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Yazarken sonuçların görüntülenmesi için, Google Arama\'yı kullanırken Google Anında Arama\'dan yararlanın (veri kullanımını artırabilir)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Tam ekran"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Durum çubuğunu gizlemek için tam ekran modunu kullanın"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Kullanıcı Aracı Değiştirici"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Bir sitenin tablet ve masaüstü sürümleri arasında geçiş yapın"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Bir sitenin tablet ve masaüstü sürümleri arasında geçiş yapmak için Android veya dizüstü bilgisayar simgesine hafifçe vurun."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Veri bağlantısı sorunu"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Sorunlu dosya"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Doğrula"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Paylaş"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Kullanılabilir başka sekme yok"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Anında Arama ile Google (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Pencereler geri yüklensin mi?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Tarayıcı kilitlenmiş görünüyor. Son kullandığınız pencerelerin geri yüklenmesini ister misiniz?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Evet"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Hayır"</string>
+ <string name="preview" msgid="1470306351083271066">"Önizleme:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Yerel"</string>
</resources>
diff --git a/res/values-uk-sw600dp/strings.xml b/res/values-uk-sw600dp/strings.xml
index c92456b..2b4f3f7 100644
--- a/res/values-uk-sw600dp/strings.xml
+++ b/res/values-uk-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Відкрити в новій фоновій вкладці"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Відкрити все в нових вкладках"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Відкривати нові вкладки за поточною"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Відновити вкладки?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Відбулося аварійне завершення роботи веб-переглядача. Відновити останні відкриті вкладки?"</string>
</resources>
diff --git a/res/values-uk-xlarge/strings.xml b/res/values-uk-xlarge/strings.xml
index 036aeaf..114653e 100644
--- a/res/values-uk-xlarge/strings.xml
+++ b/res/values-uk-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Відкрити в новій фоновій вкладці"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Відкрити все в нових вкладках"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Відкривати нові вкладки за поточною"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Відновити вкладки?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Відбулося аварійне завершення роботи веб-переглядача. Відновити останні відкриті вкладки?"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index eec1e19..2674da3 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Скасувати"</string>
<string name="location" msgid="3411848697912600125">"Адреса"</string>
+ <string name="account" msgid="5179824606448077042">"Обліковий запис"</string>
<string name="containing_folder" msgid="6771180232953030479">"Додати до"</string>
<string name="new_folder" msgid="7743540149088867917">"Нова папка"</string>
<string name="edit_folder" msgid="621817453133656156">"Редагувати папку"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Введіть і збережіть дані для полів автоматичного заповнення веб-форм"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Автоматичний вхід у Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Вхід у Google Sites за допомогою <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Доступний автоматичний вхід."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Вхід із використанням облікового запису"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Увійти"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Сховати"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Помилка входу."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Введіть дані, які автоматично підставлятимуться у веб-поля, коли ви торкатиметеся їх."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Повне ім\'я:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Дуже вел."</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Розмір тексту"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Мінімальний розмір шрифту"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Примусово ввімк. масштабування"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Чи потрібно змінюв. запит веб-сайту на контроль поведінки масштабування"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Масштаб за умовч."</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Віддал."</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Корейська (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Кодування тексту"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Доступність"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Лабораторії"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Швидкі елементи керування"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Гортайте зліва чи справа, щоб відкрити швидкі елем. керування та сховати панелі програми й URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"На вашій домашній сторінці відображаються найчастіше відвідувані веб-сторінки."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Миттєвий пошук Google"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Використовуйте Миттєвий пошук у пошуку Google для відображ. результ. під час введення (може збільшитись викорис. даних)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Повноекранний режим"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Використовуйте повноекранний режим, щоб ховати рядок стану."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Зміна користувацького агента"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Переключатися між версіями сайту для планшетного ПК і комп’ютера"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Торкніться значка Android або ноутбука, щоб переключатися між версіями сайту для планшетного ПК і комп’ютера."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Проблема з доступом до даних"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Проблема з файлом"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Підтверд."</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Надіслати"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Більше немає вкладок"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google із Миттєвим пошуком (Лабораторії)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Відновити вікна?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Відбулося аварійне завершення роботи веб-переглядача. Відновити останні відкриті вікна?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Так"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Ні"</string>
+ <string name="preview" msgid="1470306351083271066">"Перегляд:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Локальні"</string>
</resources>
diff --git a/res/values-vi-sw600dp/strings.xml b/res/values-vi-sw600dp/strings.xml
index afe596b..a4865be 100644
--- a/res/values-vi-sw600dp/strings.xml
+++ b/res/values-vi-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"Mở trong tab nền mới"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"Mở tất cả trong tab mới"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"Mở tab mới phía sau tab hiện tại"</string>
+ <string name="recover_title" msgid="1558775426269800998">"Khôi phục các tab?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"Trình duyệt dường như đã gặp sự cố. Bạn có muốn khôi phục lại các tab từ lần trước không?"</string>
</resources>
diff --git a/res/values-vi-xlarge/strings.xml b/res/values-vi-xlarge/strings.xml
index 5e74c13..4a12067 100644
--- a/res/values-vi-xlarge/strings.xml
+++ b/res/values-vi-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"Mở trong tab nền mới"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"Mở tất cả trong tab mới"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"Mở tab mới phía sau tab hiện tại"</string>
+ <string name="recover_title" msgid="7754049918641251703">"Khôi phục các tab?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"Trình duyệt có vẻ như đã gặp sự cố. Bạn có muốn khôi phục lại các tab từ lần trước không?"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d5010a4..802366a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"OK"</string>
<string name="do_not_save" msgid="6777633870113477714">"Huỷ"</string>
<string name="location" msgid="3411848697912600125">"Địa chỉ"</string>
+ <string name="account" msgid="5179824606448077042">"Tài khoản"</string>
<string name="containing_folder" msgid="6771180232953030479">"Thêm vào"</string>
<string name="new_folder" msgid="7743540149088867917">"Thư mục mới"</string>
<string name="edit_folder" msgid="621817453133656156">"Chỉnh sửa thư mục"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Nhập và lưu dữ liệu cho các trường tự động điền biểu mẫu web"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"Tự động đăng nhập Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"Đang đăng nhập vào trang web Google bằng <xliff:g id="ID_1">%s</xliff:g>"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"Tính năng đăng nhập tự động hiện khả dụng."</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"Đăng nhập với tên"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"Đăng nhập"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"Ẩn"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"Đăng nhập không thành công."</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"Nhập dữ liệu bạn muốn để tự động điền vào các trường trên web khi bạn gặp chúng."</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"Tên đầy đủ:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"Rất lớn"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"Kích cỡ chữ"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"Kích thước phông chữ tối thiểu"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"Bắt buộc bật thu phóng"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"Gh.đè y/c tr.web để k.s t.phóng"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"Thu phóng mặc định"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"Xa"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"Tiếng Hàn (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Mã hoá văn bản"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"Khả năng truy cập"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"Lab"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"Các điều khiển nhanh"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"Trượt ngón tay từ cạnh trái hoặc phải để truy cập điều khiển nhanh và ẩn các thanh Ứng dụng và URL"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"Trang chủ hiển thị các trang web được truy cập nhiều nhất của bạn."</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google Instant"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"Sử dụng Google Instant khi bạn sử dụng Tìm kiếm của Google để hiển thị kết quả khi nhập (điều này có thể tăng việc sử dụng dữ liệu)."</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"Toàn màn hình"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"Sử dụng chế độ toàn màn hình để ẩn thanh trạng thái."</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Trình chuyển đổi tác nhân người dùng"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"Chuyển giữa các phiên bản dành cho máy tính bảng và máy tính để bàn của trang web"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"Bấm vào biểu tượng Android hoặc máy tính xách tay để chuyển giữa các phiên bản dành cho máy tính bảng và máy tính để bàn của trang web."</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"Sự cố kết nối dữ liệu"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"Sự cố với tệp"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"Xác nhận"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"Chia sẻ"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"Không có thêm tab nào"</string>
<string name="instant_search_label" msgid="8769284297650716935">"Google với tính năng Instant (Labs)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"Khôi phục các cửa sổ?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"Trình duyệt có vẻ như đã gặp sự cố. Bạn có muốn khôi phục lại các cửa sổ từ lần trước không?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"Có"</string>
+ <string name="recover_no" msgid="3121030267940592611">"Không"</string>
+ <string name="preview" msgid="1470306351083271066">"Xem trước:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"Địa phương"</string>
</resources>
diff --git a/res/values-w720dp/bools.xml b/res/values-w720dp/bools.xml
deleted file mode 100644
index 0d05b7f..0000000
--- a/res/values-w720dp/bools.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2011 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <bool name="hide_nav_buttons">false</bool>
-</resources>
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
new file mode 100644
index 0000000..4951b2e
--- /dev/null
+++ b/res/values-xlarge/styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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>
+ <style name="BrowserTheme" parent="@android:Theme.Holo">
+ <item name="android:windowBackground">@color/white</item>
+ <item name="android:colorBackground">#FFFFFFFF</item>
+ <item name="android:windowActionBar">true</item>
+ <item name="android:windowNoTitle">false</item>
+ <item name="android:actionBarStyle">@style/ActionBarStyle</item>
+ <item name="android:actionButtonStyle">@style/ActionButton</item>
+ </style>
+</resources>
diff --git a/res/values-zh-rCN-sw600dp/strings.xml b/res/values-zh-rCN-sw600dp/strings.xml
index c9913fc..76f8940 100644
--- a/res/values-zh-rCN-sw600dp/strings.xml
+++ b/res/values-zh-rCN-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"在新的后台标签页中打开"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"在新标签页中打开全部书签"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"在当前标签页后方打开新标签页"</string>
+ <string name="recover_title" msgid="1558775426269800998">"要恢复标签页吗?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"浏览器似乎已崩溃。要恢复最后一次打开的标签页吗?"</string>
</resources>
diff --git a/res/values-zh-rCN-xlarge/strings.xml b/res/values-zh-rCN-xlarge/strings.xml
index b64a476..5ae13e5 100644
--- a/res/values-zh-rCN-xlarge/strings.xml
+++ b/res/values-zh-rCN-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"在新的后台标签页中打开"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"在新标签页中打开全部书签"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"在当前标签页后方打开新标签页"</string>
+ <string name="recover_title" msgid="7754049918641251703">"恢复标签页?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"浏览器似乎已崩溃。要恢复最后一次打开的标签页吗?"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index ed5f8e1..d1de8b1 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"确定"</string>
<string name="do_not_save" msgid="6777633870113477714">"取消"</string>
<string name="location" msgid="3411848697912600125">"地址"</string>
+ <string name="account" msgid="5179824606448077042">"帐户"</string>
<string name="containing_folder" msgid="6771180232953030479">"添加到"</string>
<string name="new_folder" msgid="7743540149088867917">"新建文件夹"</string>
<string name="edit_folder" msgid="621817453133656156">"修改文件夹"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"输入并保存网络表单自动填充字段的数据"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"自动登录 Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"正使用 <xliff:g id="ID_1">%s</xliff:g> 登录 Google 网站"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"自动登录已可使用。"</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"使用以下身份登录:"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"登录"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"隐藏"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"登录失败。"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"请在网络字段中输入希望触摸时自动填充的数据。"</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"全名:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"超大"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"文字大小"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"字体大小下限"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"强制启用缩放"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"是否通过替换网站的请求来控制缩放行为"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"默认缩放设置"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"远"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"韩语 (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"文字编码"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"辅助功能"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"实验室"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"快速控制"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"从左边缘或右边缘滑动拇指即可访问快速控制并隐藏应用程序和网址栏"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"您的主页会显示最常访问的网页。"</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google 即搜即得"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"借助 Google 即搜即得,您可以在使用 Google 搜索时一边键入内容一边查看结果(此功能可能会增加数据使用量)。"</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"全屏"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"使用全屏模式可隐藏状态栏。"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"Useragent 切换器"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"在网站的平板电脑版和桌面版之间进行切换"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"点按 Android 或笔记本电脑图标,在网站的平板电脑版和桌面版之间进行切换。"</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"数据连接性问题"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"文件有问题"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"确认"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"分享"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"没有更多标签可用"</string>
<string name="instant_search_label" msgid="8769284297650716935">"具有即搜即得功能的 Google(实验室)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"恢复窗口?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"浏览器似乎已崩溃。要恢复最后一次打开的窗口吗?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"是"</string>
+ <string name="recover_no" msgid="3121030267940592611">"否"</string>
+ <string name="preview" msgid="1470306351083271066">"预览:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"本地"</string>
</resources>
diff --git a/res/values-zh-rTW-sw600dp/strings.xml b/res/values-zh-rTW-sw600dp/strings.xml
index 8bb6ef4..b55e845 100644
--- a/res/values-zh-rTW-sw600dp/strings.xml
+++ b/res/values-zh-rTW-sw600dp/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="7104473293755016241">"在新背景分頁中開啟連結"</string>
<string name="open_all_in_new_window" msgid="4294281492905397499">"在新分頁中開啟所有書籤"</string>
<string name="pref_content_open_in_background_summary" msgid="4799440480107121813">"在目前分頁的後面開啟新分頁"</string>
+ <string name="recover_title" msgid="1558775426269800998">"還原分頁?"</string>
+ <string name="recover_prompt" msgid="3793203259958951755">"瀏覽器已當機,您要還原當機前開啟的分頁嗎?"</string>
</resources>
diff --git a/res/values-zh-rTW-xlarge/strings.xml b/res/values-zh-rTW-xlarge/strings.xml
index 32c2158..9d2881b 100644
--- a/res/values-zh-rTW-xlarge/strings.xml
+++ b/res/values-zh-rTW-xlarge/strings.xml
@@ -23,4 +23,6 @@
<string name="contextmenu_openlink_newwindow_background" msgid="5625314148071601758">"在新背景分頁中開啟連結"</string>
<string name="open_all_in_new_window" msgid="8498279523071618315">"於新分頁開啟所有書籤"</string>
<string name="pref_content_open_in_background_summary" msgid="7653600574808720292">"在目前分頁的後面開啟新分頁"</string>
+ <string name="recover_title" msgid="7754049918641251703">"還原標籤?"</string>
+ <string name="recover_prompt" msgid="3030249435588073132">"瀏覽器似乎當機了。您想要還原最後一次的標籤嗎?"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 96e1e57..461b621 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -65,6 +65,7 @@
<string name="save" msgid="5922311934992468496">"確定"</string>
<string name="do_not_save" msgid="6777633870113477714">"取消"</string>
<string name="location" msgid="3411848697912600125">"地址"</string>
+ <string name="account" msgid="5179824606448077042">"帳戶"</string>
<string name="containing_folder" msgid="6771180232953030479">"新增至"</string>
<string name="new_folder" msgid="7743540149088867917">"新資料夾"</string>
<string name="edit_folder" msgid="621817453133656156">"編輯資料夾"</string>
@@ -172,8 +173,9 @@
<string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"輸入並儲存資料,以供自動填入表單欄位時使用"</string>
<string name="pref_autologin_title" msgid="2362827272595366379">"自動登入 Google"</string>
<string name="pref_autologin_progress" msgid="8333244467048833461">"正使用 <xliff:g id="ID_1">%s</xliff:g> 登入 Google 網站"</string>
- <string name="autologin_bar_text" msgid="8013977161879448141">"可自動登入。"</string>
+ <string name="autologin_bar_text" msgid="3684581827167173371">"登入身分"</string>
<string name="autologin_bar_login_text" msgid="7052816600314556734">"登入"</string>
+ <string name="autologin_bar_hide_text" msgid="3629355974385859580">"隱藏"</string>
<string name="autologin_bar_error" msgid="5132514366023044839">"登入失敗。"</string>
<string name="autofill_profile_editor_heading" msgid="8392952553626722083">"輸入您輕觸網頁欄位時要自動填入的資料。"</string>
<string name="autofill_profile_editor_name" msgid="8566130291459685955">"全名:"</string>
@@ -238,6 +240,9 @@
<item msgid="7201512237890458902">"最大"</item>
</string-array>
<string name="pref_text_size_dialogtitle" msgid="3625388833512647865">"文字大小"</string>
+ <string name="pref_min_font_size" msgid="8811125835817449131">"最小字型大小"</string>
+ <string name="pref_force_userscalable" msgid="5641500562399892621">"強制啟用縮放功能"</string>
+ <string name="pref_force_userscalable_summary" msgid="4431962409438162448">"是否覆寫網站的控制縮放行為要求"</string>
<string name="pref_default_zoom" msgid="8076142259097187395">"預設縮放"</string>
<string-array name="pref_default_zoom_choices">
<item msgid="549583171195154919">"遠"</item>
@@ -268,6 +273,7 @@
<item msgid="2193955365569270096">"韓文 (EUC-KR)"</item>
</string-array>
<string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"文字編碼"</string>
+ <string name="pref_accessibility_title" msgid="5127836981587423215">"協助工具"</string>
<string name="pref_lab_title" msgid="5571091610359629423">"研究室"</string>
<string name="pref_lab_quick_controls" msgid="3267606522082281367">"快速控制介面"</string>
<string name="pref_lab_quick_controls_summary" msgid="1564546156544675707">"於左右邊緣滑動拇指即可使用快速控制介面,以及隱藏應用程式列和網址列"</string>
@@ -275,6 +281,11 @@
<string name="pref_lab_most_visited_homepage_summary" msgid="4132511544800457513">"首頁會顯示您最常瀏覽的網頁。"</string>
<string name="pref_use_instant_search" msgid="1119176077760723740">"Google 互動智慧搜尋"</string>
<string name="pref_use_instant_search_summary" msgid="839320474961917522">"使用「Google 搜尋」時啟用「Google 互動智慧搜尋」功能,您輸入查詢時可以即時獲得顯示搜尋結果 (這會增加資料傳輸量)。"</string>
+ <string name="pref_lab_fullscreen" msgid="8173609016657987973">"全螢幕"</string>
+ <string name="pref_lab_fullscreen_summary" msgid="6853711692160711419">"使用全螢幕模式以隱藏狀態列。"</string>
+ <string name="pref_enable_useragent_switcher" msgid="9063310468293037499">"使用者代理程式切換功能"</string>
+ <string name="pref_enable_useragent_switcher_summary" msgid="1782363693543953474">"切換平板電腦版本的網站和桌上型電腦版本的網站"</string>
+ <string name="help_useragent_switcher" msgid="123586256526014375">"輕按 Android 或筆記型電腦圖示,即可切換平板電腦版本的網站和桌上型電腦版本的網站。"</string>
<string name="browserFrameNetworkErrorLabel" msgid="126892350904924893">"資料連線問題"</string>
<string name="browserFrameFileErrorLabel" msgid="8063691502792670367">"檔案有問題"</string>
<string name="browserFrameFormResubmitLabel" msgid="2685923472682180360">"確認"</string>
@@ -382,4 +393,10 @@
<string name="menu_share_url" msgid="5851814357333739700">"分享"</string>
<string name="max_tabs_warning" msgid="4122034303809457570">"已無分頁可供使用"</string>
<string name="instant_search_label" msgid="8769284297650716935">"使用 Google 互動智慧搜尋 (研究室)"</string>
+ <string name="recover_title" msgid="8095611702406163360">"還原視窗?"</string>
+ <string name="recover_prompt" msgid="5526783279696786755">"瀏覽器似乎當機了。您想要還原最後一次的視窗嗎?"</string>
+ <string name="recover_yes" msgid="5837971910598069183">"好"</string>
+ <string name="recover_no" msgid="3121030267940592611">"不用了"</string>
+ <string name="preview" msgid="1470306351083271066">"預覽:"</string>
+ <string name="local_bookmarks" msgid="533816851415228520">"本機"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
new file mode 100644
index 0000000..115d17d
--- /dev/null
+++ b/res/values-zu/strings.xml
@@ -0,0 +1,622 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 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" msgid="1935869255545976415">"Isiphequluli"</string>
+ <string name="choose_upload" msgid="3649366287575002063">"Khetha ifayela yokulayisha"</string>
+ <!-- no translation found for uploads_disabled (463761197575372994) -->
+ <skip />
+ <string name="new_tab" msgid="4505722538297295141">"Iwindi elisha"</string>
+ <string name="new_incognito_tab" msgid="5821404839654751753">"Iwindi elisha le-incognito"</string>
+ <string name="active_tabs" msgid="3050623868203544623">"I-Windows"</string>
+ <string name="tab_bookmarks" msgid="2305793036003473653">"Amabhukimakhi"</string>
+ <string name="tab_most_visited" msgid="1077402532455000703">"Okuvakashelwa njalo"</string>
+ <string name="tab_history" msgid="1979267558744613746">"Umlando"</string>
+ <string name="added_to_bookmarks" msgid="1020224130695956728">"Amabhukimakhi afakiwe"</string>
+ <string name="removed_from_bookmarks" msgid="6063705902028438800">"Ikhishwe kumabhukimakhi"</string>
+ <string name="sign_in_to" msgid="5939425800148759165">"Ngena ngemvume ku-\"<xliff:g id="HOSTNAME">%s1</xliff:g>\" \"<xliff:g id="REALM">%s2</xliff:g>\""</string>
+ <!-- no translation found for username (5057566336518215922) -->
+ <skip />
+ <!-- no translation found for password (1177138552305184404) -->
+ <skip />
+ <!-- no translation found for action (183105774472071343) -->
+ <skip />
+ <string name="bookmarks_search" msgid="5229596268214362873">"Isiphequluli"</string>
+ <!-- no translation found for cancel (3017274947407233702) -->
+ <skip />
+ <!-- no translation found for ok (1509280796718850364) -->
+ <skip />
+ <string name="title_bar_loading" msgid="7438217780834640678">"Iyalayisha..."</string>
+ <!-- no translation found for page_info (4048529256302257195) -->
+ <skip />
+ <!-- no translation found for page_info_view (5303490449842635158) -->
+ <skip />
+ <!-- no translation found for page_info_address (2222306609532903254) -->
+ <skip />
+ <!-- no translation found for ssl_warnings_header (79744901983636370) -->
+ <skip />
+ <!-- no translation found for ssl_continue (8031515015829358457) -->
+ <skip />
+ <!-- no translation found for security_warning (6607795404322797541) -->
+ <skip />
+ <!-- no translation found for view_certificate (1472768887529093862) -->
+ <skip />
+ <!-- no translation found for ssl_go_back (4598951822061593819) -->
+ <skip />
+ <!-- no translation found for ssl_untrusted (5369967226521102194) -->
+ <skip />
+ <!-- no translation found for ssl_mismatch (558688832420069896) -->
+ <skip />
+ <!-- no translation found for ssl_expired (5739349389499575559) -->
+ <skip />
+ <!-- no translation found for ssl_not_yet_valid (2893167846212645846) -->
+ <skip />
+ <!-- no translation found for ssl_certificate (5226747157992111668) -->
+ <skip />
+ <!-- no translation found for ssl_certificate_is_valid (7096160815933145579) -->
+ <skip />
+ <!-- no translation found for issued_to (9032338008819841339) -->
+ <skip />
+ <!-- no translation found for common_name (5745530093500062357) -->
+ <skip />
+ <!-- no translation found for org_name (8868889052889991293) -->
+ <skip />
+ <!-- no translation found for org_unit (4489056376307768196) -->
+ <skip />
+ <!-- no translation found for issued_by (6959484326943152487) -->
+ <skip />
+ <!-- no translation found for validity_period (57988851973181309) -->
+ <skip />
+ <!-- no translation found for issued_on (2082890654801808368) -->
+ <skip />
+ <!-- no translation found for expires_on (8061200430557020704) -->
+ <skip />
+ <!-- no translation found for stopping (4839698519340302982) -->
+ <skip />
+ <!-- no translation found for stop (5687251076030630074) -->
+ <skip />
+ <!-- no translation found for reload (8585220783228408062) -->
+ <skip />
+ <!-- no translation found for back (8414603107175713668) -->
+ <skip />
+ <!-- no translation found for forward (4288210890526641577) -->
+ <skip />
+ <!-- no translation found for save (5922311934992468496) -->
+ <skip />
+ <!-- no translation found for do_not_save (6777633870113477714) -->
+ <skip />
+ <string name="location" msgid="3411848697912600125">"Ikheli"</string>
+ <!-- no translation found for account (5179824606448077042) -->
+ <skip />
+ <string name="containing_folder" msgid="6771180232953030479">"Yengeza ku-"</string>
+ <string name="new_folder" msgid="7743540149088867917">"Ifolda entsha"</string>
+ <!-- no translation found for edit_folder (621817453133656156) -->
+ <skip />
+ <!-- no translation found for delete_folder (2046483129024501116) -->
+ <skip />
+ <!-- no translation found for no_subfolders (5880411440592452802) -->
+ <skip />
+ <!-- no translation found for add_to_bookmarks_menu_option (4449323955122214389) -->
+ <skip />
+ <!-- no translation found for add_to_homescreen_menu_option (1461447829242963790) -->
+ <skip />
+ <!-- no translation found for add_to_other_folder_menu_option (5450890093372998187) -->
+ <skip />
+ <string name="name" msgid="5462672162695365387">"Ilebula"</string>
+ <!-- no translation found for http (2163722670597250102) -->
+ <skip />
+ <string name="save_to_bookmarks" msgid="6101482434920313244">"Yengeza Kumabhukimakhi"</string>
+ <string name="bookmark_this_page" msgid="7530739804320811054">"Beka uphawu lokubekisa kuleli khasi"</string>
+ <string name="remove" msgid="7820112494467011374">"Khipha"</string>
+ <!-- no translation found for edit_bookmark (5024089053490231905) -->
+ <skip />
+ <string name="create_shortcut_bookmark" msgid="1995095662095484289">"Yengeza izinqamuleli ekhaya"</string>
+ <!-- no translation found for open_bookmark (8473581305759935790) -->
+ <skip />
+ <!-- no translation found for remove_bookmark (8407495852801410891) -->
+ <skip />
+ <string name="remove_from_bookmarks" msgid="4374080666576982775">"Khipha kumabhukimakhi"</string>
+ <!-- no translation found for remove_history_item (5021424935726728618) -->
+ <skip />
+ <string name="set_as_homepage" msgid="4752937379414905560">"Hlela njengekhasi eliyisiqalo"</string>
+ <!-- no translation found for bookmark_saved (2766434679871317557) -->
+ <skip />
+ <string name="bookmark_not_saved" msgid="700600955089376724">"Ayikwazi ukugcina ibhukimakhi."</string>
+ <string name="homepage_set" msgid="8768087280310966395">"Hlela ikhasi eliyisiqalo."</string>
+ <string name="bookmark_needs_title" msgid="6245900436119218187">"Ibhukimakhi kumele ibe negama"</string>
+ <string name="bookmark_needs_url" msgid="7809876865972755158">"Ibhukimakhi kumele ibe nendawo."</string>
+ <!-- no translation found for bookmark_url_not_valid (6719785633980202419) -->
+ <skip />
+ <string name="bookmark_cannot_save_url" msgid="791722768778386941">"Le-URL ayikwazi ukubhukimakhiwa."</string>
+ <!-- no translation found for delete_bookmark (2422989994934201992) -->
+ <skip />
+ <!-- no translation found for bookmark_page (6845189305130307274) -->
+ <skip />
+ <!-- no translation found for bookmark_thumbnail_view (3164068314718522138) -->
+ <skip />
+ <!-- no translation found for bookmark_list_view (7848510619500937839) -->
+ <skip />
+ <string name="current_page" msgid="7510129573681663135">"kusuka ku "</string>
+ <string name="delete_bookmark_warning" msgid="758043186202032205">"Ibhukimakhi \"<xliff:g id="BOOKMARK">%s</xliff:g>\" izosuswa."</string>
+ <!-- no translation found for open_all_in_new_window (6514602245828366045) -->
+ <skip />
+ <string name="goto_dot" msgid="3895839050522602723">"Iya"</string>
+ <string name="incognito_tab" msgid="5419458065370134289">"Vula ithebhu entsha ye-incognito"</string>
+ <string name="select_dot" msgid="6299170761900561967">"Khetha umbhalo"</string>
+ <!-- no translation found for tab_picker_title (864478399057782913) -->
+ <skip />
+ <!-- no translation found for tab_picker_remove_tab (630087809802479397) -->
+ <skip />
+ <!-- no translation found for bookmarks (1961279134885867815) -->
+ <skip />
+ <!-- no translation found for shortcut_bookmark (3974876480401135895) -->
+ <skip />
+ <!-- no translation found for history (2451240511251410032) -->
+ <skip />
+ <!-- no translation found for menu_view_download (2124570321712995120) -->
+ <skip />
+ <string name="copy_page_url" msgid="7635062169011319208">"Kopisha i-url yekhasi"</string>
+ <!-- no translation found for share_page (593756995297268343) -->
+ <skip />
+ <!-- outdated translation 3934652434001459581 --> <string name="menu_save_webarchive" msgid="2474117375302625691">"Londoloza njengeSigcinamlando seWebhu."</string>
+ <!-- outdated translation 7045250341467345007 --> <string name="webarchive_saved" msgid="2212053339474523406">"Isigcinamlando sewebhu silondoloziwe."</string>
+ <!-- outdated translation 2880998204746620260 --> <string name="webarchive_failed" msgid="19950914584285713">"Yehlulekile ukulondoloza isigcinamlando sewebhu."</string>
+ <!-- no translation found for contextheader_folder_bookmarkcount (353987136645619089) -->
+ <skip />
+ <!-- no translation found for contextheader_folder_empty (974171637803391651) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink (7237961252214188935) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow (992765050093960353) -->
+ <skip />
+ <!-- no translation found for contextmenu_openlink_newwindow_background (5556131402560251639) -->
+ <skip />
+ <!-- no translation found for contextmenu_savelink (5508554930832538184) -->
+ <skip />
+ <!-- no translation found for contextmenu_sharelink (5392275392280130331) -->
+ <skip />
+ <!-- no translation found for contextmenu_copy (398860586635404030) -->
+ <skip />
+ <!-- no translation found for contextmenu_copylink (5153657160294534270) -->
+ <skip />
+ <!-- no translation found for contextmenu_download_image (4243829645180686912) -->
+ <skip />
+ <!-- no translation found for contextmenu_view_image (3870625602053600905) -->
+ <skip />
+ <string name="contextmenu_set_wallpaper" msgid="3691902960115350686">"Hlela njengephephadonga"</string>
+ <!-- no translation found for contextmenu_dial_dot (5856550683415933806) -->
+ <skip />
+ <!-- no translation found for contextmenu_add_contact (3183511922223645716) -->
+ <skip />
+ <!-- no translation found for contextmenu_send_mail (1014513374828775660) -->
+ <skip />
+ <!-- no translation found for contextmenu_map (7471390435434034912) -->
+ <skip />
+ <string name="choosertitle_sharevia" msgid="4600490613341909086">"Abelana nge"</string>
+ <!-- no translation found for clear (7070043081700011461) -->
+ <skip />
+ <!-- no translation found for replace (4843033491070384047) -->
+ <skip />
+ <!-- no translation found for browser_bookmarks_page_bookmarks_text (6787605028726162673) -->
+ <skip />
+ <!-- no translation found for menu_preferences (6709237687234102240) -->
+ <skip />
+ <!-- no translation found for pref_content_title (722227111894838633) -->
+ <skip />
+ <!-- no translation found for pref_content_load_images (2125616852957377561) -->
+ <skip />
+ <string name="pref_content_load_images_summary" msgid="5055874125248398584">"Bonisa imifanekiso emakhasini lewebhu"</string>
+ <!-- no translation found for pref_content_block_popups (4158524847764470895) -->
+ <skip />
+ <!-- no translation found for pref_content_javascript (4570972030299516843) -->
+ <skip />
+ <!-- no translation found for pref_content_open_in_background (824123779725118663) -->
+ <skip />
+ <string name="pref_content_plugins" msgid="7231944644794301582">"Vumela intshutheko"</string>
+ <string-array name="pref_content_plugins_choices">
+ <item msgid="6745108155096660725">"Njalo ivuliwe"</item>
+ <item msgid="2484126708670016519">"Kuyadingeka kakhulu"</item>
+ <item msgid="8547442717307793863">"Valiwe"</item>
+ </string-array>
+ <string name="pref_content_open_in_background_summary" msgid="1737664075721181678">"Vula amawindi amasha emva kwamanje"</string>
+ <!-- no translation found for pref_content_homepage (3324574611613105696) -->
+ <skip />
+ <string name="pref_content_search_engine" msgid="1620101310821644144">"Hlela injini yokusesha"</string>
+ <string name="pref_content_search_engine_summary" msgid="5162667665858487316">"Khetha injini yokusesha"</string>
+ <!-- no translation found for pref_set_homepage_to (7196350233061395098) -->
+ <skip />
+ <!-- outdated translation 1493179933653044553 --> <string name="pref_use_current" msgid="1778622474040406672">"Sebenzisa ikhasi lamanje"</string>
+ <!-- no translation found for pref_use_blank (8503238592551111169) -->
+ <skip />
+ <!-- no translation found for pref_use_default (192587563274735878) -->
+ <skip />
+ <!-- no translation found for pref_content_autofit (8260474534053660809) -->
+ <skip />
+ <string name="pref_content_autofit_summary" msgid="4587831659894879986">"Lungisa amakhasi ewebhu ukulingana kwisikrini"</string>
+ <!-- no translation found for pref_general_title (1946872771219249323) -->
+ <skip />
+ <!-- no translation found for pref_general_sync_title (3138637035975860324) -->
+ <skip />
+ <!-- no translation found for pref_general_autofill_title (547881256865816858) -->
+ <skip />
+ <string name="pref_personal_sync_with_chrome" msgid="1695182180332194033">"Vumelanisa ne-Google Chrome"</string>
+ <string name="pref_personal_sync_with_chrome_summary" msgid="7414133931827321055">"Abelana namabhukimakhi & enye idatha phakathi kweSiphequluli se-Android ne-Google Chrome"</string>
+ <string name="pref_personal_google_account" msgid="952360133341490071">"I-akhawunti ye-Google"</string>
+ <string name="pref_personal_sync_bookmarks" msgid="59237515966184432">"Vumelanisa amabhukimakhi"</string>
+ <string name="pref_personal_sync_bookmarks_summary" msgid="4791767605662205482">"Vumelanisa amabhukimakhi phakathi Nesiphequluli se-Android kanye ne-Google Chrome"</string>
+ <string name="pref_personal_start_syncing" msgid="6046972042512655232">"Qalisa ukuvumelanisa"</string>
+ <string name="pref_personal_account_dialog_title" msgid="1390867119887955530">"Khetha i-akhawunti ye-Google ozokwabelana nayo"</string>
+ <!-- outdated translation 1174197447388234595 --> <string name="pref_autofill_enabled" msgid="1015751713312396713">"Ifomu Yokugcwalisa Okuzenzakalelayo"</string>
+ <string name="pref_autofill_enabled_summary" msgid="422640696197018914">"Gcwalisa amafomu ewebhu ngokuchofoza okukodwa"</string>
+ <!-- outdated translation 1350709161524642663 --> <string name="pref_autofill_profile_editor" msgid="3864116896052437796">"Izilungiselelo Zokugcwalisa Okuzenzakalelayo"</string>
+ <!-- unknown quoting pattern: original -1, translation 1 -->
+ <!-- outdated translation 6748434431641768870 --> <string name="pref_autofill_profile_editor_summary" msgid="3653552312512743181">"Hlela &amp; phatha idatha yamafomu Agcwaliswe Ngokuzenzakalelayo"</string>
+ <!-- no translation found for pref_autologin_title (2362827272595366379) -->
+ <skip />
+ <!-- no translation found for pref_autologin_progress (8333244467048833461) -->
+ <skip />
+ <!-- no translation found for autologin_bar_text (3684581827167173371) -->
+ <skip />
+ <!-- no translation found for autologin_bar_login_text (7052816600314556734) -->
+ <skip />
+ <!-- no translation found for autologin_bar_hide_text (3629355974385859580) -->
+ <skip />
+ <!-- no translation found for autologin_bar_error (5132514366023044839) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_heading (8392952553626722083) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_name (8566130291459685955) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_email_address (7967585896612797173) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_company_name (2813443159949210417) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1 (836433242509243081) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_1_hint (5965659598509327172) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2 (8194745202893822479) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_address_line_2_hint (2048330295853546405) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_city (4193225955409148508) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_state (8549739922338171458) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_zip_code (283668573295656671) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_country (7234470301239156656) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number (4938852821413729276) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_phone_number_invalid (7166394872369167580) -->
+ <skip />
+ <string name="autofill_profile_editor_save_profile" msgid="8349915287435262888">"Gcina iphrofayli"</string>
+ <!-- no translation found for autofill_profile_successful_save (6834102203944938409) -->
+ <skip />
+ <!-- no translation found for autofill_profile_successful_delete (2421442112954362732) -->
+ <skip />
+ <!-- no translation found for autofill_profile_editor_delete_profile (2754563301088418752) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_message (6605682320156223114) -->
+ <skip />
+ <!-- no translation found for autofill_setup_dialog_negative_toast (6990737008936188620) -->
+ <skip />
+ <!-- no translation found for disable_autofill (8305901059849400354) -->
+ <skip />
+ <!-- no translation found for pref_privacy_security_title (3480313968942160914) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cache (3380316479925886998) -->
+ <skip />
+ <string name="pref_privacy_clear_cache_summary" msgid="2216463577207991454">"Sula okuqukethwe okulondolozwa okwesikhashana kwasendaweni nezizinda zemininingwane"</string>
+ <string name="pref_privacy_clear_cache_dlg" msgid="5541011591300753881">"Okuqekethwe okulondolozwe okwesikhashana kwasendaweni nezizinda zemininingwane kuzosuswa."</string>
+ <!-- no translation found for pref_privacy_cookies_title (6763274282214830526) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_cookies (3095583579133780331) -->
+ <skip />
+ <string name="pref_privacy_clear_cookies_summary" msgid="6962742063990677520">"Sula wonke amakhukhi okuphequlula"</string>
+ <string name="pref_privacy_clear_cookies_dlg" msgid="552855688091432682">"Wonke amakhukhi azosuswa."</string>
+ <!-- no translation found for pref_privacy_clear_history (8723795508825198477) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_history_summary (6868501330708940734) -->
+ <skip />
+ <string name="pref_privacy_clear_history_dlg" msgid="544903007914753853">"Umlando wokuzulazula wesiphequluli uzosuswa."</string>
+ <!-- no translation found for pref_privacy_formdata_title (6549813837982050424) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data (4232668196344383987) -->
+ <skip />
+ <!-- no translation found for pref_privacy_clear_form_data_summary (1790390894719517167) -->
+ <skip />
+ <string name="pref_privacy_clear_form_data_dlg" msgid="4443621086781197928">"Yonke idatha yefomu elondoloziwe izosuwa."</string>
+ <!-- no translation found for pref_privacy_clear_passwords (4750234112289277480) -->
+ <skip />
+ <string name="pref_privacy_clear_passwords_summary" msgid="8856782718942903335">"Sula wonke amaphasiwedi agciniwe"</string>
+ <string name="pref_privacy_clear_passwords_dlg" msgid="2083869328824248255">"Wonke amaphasiwedi agciniwe azosuswa."</string>
+ <!-- no translation found for pref_privacy_location_title (7458378016606081067) -->
+ <skip />
+ <string name="pref_privacy_enable_geolocation" msgid="1395040170290765686">"Vumela indawo"</string>
+ <string name="pref_privacy_enable_geolocation_summary" msgid="8437020934664306205">"Vumela amasayithi ukucela ukufinyelela kundawo yakho"</string>
+ <string name="pref_privacy_clear_geolocation_access" msgid="6649680770030042980">"Sula ukufinyelela indawo"</string>
+ <string name="pref_privacy_clear_geolocation_access_summary" msgid="7750143359497314679">"Sula ukufinyelela indawo kwawo wonke amawebhusayithi"</string>
+ <string name="pref_privacy_clear_geolocation_access_dlg" msgid="7327063124488827244">"Sula ukufinyelela indawo kwawo wonke amawebhusayithi"</string>
+ <!-- no translation found for pref_security_passwords_title (5734190542383756711) -->
+ <skip />
+ <!-- no translation found for pref_security_remember_passwords (6492957683454529549) -->
+ <skip />
+ <string name="pref_security_remember_passwords_summary" msgid="256388703356349137">"Londoloza amagama omesebenzisi namaphasiwedi amawebhusayithi"</string>
+ <!-- no translation found for pref_security_save_form_data (1213669802810198893) -->
+ <skip />
+ <!-- no translation found for pref_security_save_form_data_summary (4994074685153708026) -->
+ <skip />
+ <!-- no translation found for pref_security_show_security_warning (8901135676266754559) -->
+ <skip />
+ <string name="pref_security_show_security_warning_summary" msgid="8968906112720511704">"Bonisa isexwayiso uma kunenkinga ngokuphepha kwesayithi."</string>
+ <!-- no translation found for pref_security_accept_cookies (3201367661925047989) -->
+ <skip />
+ <string name="pref_security_accept_cookies_summary" msgid="1465118934875026920">"Vumela amasayithi ukugcina nokufunda idatha \"yekhukhi\""</string>
+ <!-- no translation found for pref_text_size (3827031324346612208) -->
+ <skip />
+ <string-array name="pref_text_size_choices">
+ <item msgid="4952686548944739548">"Ncane"</item>
+ <item msgid="1950030433642671460">"Ncane"</item>
+ <item msgid="4338347520133294584">"Kuvamile"</item>
+ <item msgid="5043128215356351184">"Okukhulu"</item>
+ <item msgid="7201512237890458902">"Khulu"</item>
+ </string-array>
+ <!-- no translation found for pref_text_size_dialogtitle (3625388833512647865) -->
+ <skip />
+ <!-- no translation found for pref_min_font_size (8811125835817449131) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable (5641500562399892621) -->
+ <skip />
+ <!-- no translation found for pref_force_userscalable_summary (4431962409438162448) -->
+ <skip />
+ <string name="pref_default_zoom" msgid="8076142259097187395">"Ukusondeza okuzenzakalelayo"</string>
+ <string-array name="pref_default_zoom_choices">
+ <item msgid="549583171195154919">"Kude"</item>
+ <item msgid="5619034257768161024">"Okulingene"</item>
+ <item msgid="3840999588443167001">"Vala"</item>
+ </string-array>
+ <string name="pref_default_zoom_dialogtitle" msgid="6095974367125109021">"Ukusondeza okuzenzakalelayo"</string>
+ <string name="pref_content_load_page" msgid="2219810141690955452">"Vula amakhasi ngokufingqiwe"</string>
+ <string name="pref_content_load_page_summary" msgid="8792093504054149369">"Bonisa okufingqiwe kwamakhasi asanda kuvulwa"</string>
+ <!-- no translation found for pref_extras_title (7075456173747370647) -->
+ <skip />
+ <string name="pref_extras_website_settings" msgid="67866640052455549">"Izilungiselelo zewebhusayithi"</string>
+ <string name="pref_extras_website_settings_summary" msgid="1656771443223494406">"Izilungiselelo ezithuthukisiwe zamawebhusayithi omuntu ngamunye"</string>
+ <!-- no translation found for pref_extras_reset_default_title (3579760449455761762) -->
+ <skip />
+ <!-- no translation found for pref_extras_reset_default (8904000515846202110) -->
+ <skip />
+ <string name="pref_extras_reset_default_summary" msgid="4247870778270414501">"Buyisela esimweni izilungiselelo ezizenzakalelayo"</string>
+ <string name="pref_extras_reset_default_dlg" msgid="6640261575874704022">"Izilungiselelo zizobuyela kumanani okuzenzakalelayo."</string>
+ <!-- no translation found for pref_extras_reset_default_dlg_title (2250334970728938936) -->
+ <skip />
+ <!-- no translation found for pref_development_title (3263854204533056480) -->
+ <skip />
+ <string name="pref_default_text_encoding" msgid="5742965543955558478">"Umbhalo wekhodi wokubhaliwe"</string>
+ <string-array name="pref_default_text_encoding_choices">
+ <item msgid="7275223955790513818">"isi-Latin- 1 (ISO-8859-1)"</item>
+ <item msgid="2456597866837587140">"Ukungabhali ngemfihlo (UTF-8)"</item>
+ <item msgid="6122474363777211732">"isi-Chinese (GBK)"</item>
+ <item msgid="373372275931607040">"isi-Chinese (Big 5)"</item>
+ <item msgid="891615911084608570">"isi-Japanese (ISO-2022-JP)"</item>
+ <item msgid="5589150448475151241">"isi-Japanese (SHIFT_JIS)"</item>
+ <item msgid="7356792686950371843">"isi-Japanese (EUC-JP)"</item>
+ <item msgid="2193955365569270096">"isi-Korean (EUC-KR)"</item>
+ </string-array>
+ <string name="pref_default_text_encoding_dialogtitle" msgid="5508255018084978547">"Umbhalo wekhodi wokubhaliwe"</string>
+ <!-- no translation found for pref_accessibility_title (5127836981587423215) -->
+ <skip />
+ <!-- no translation found for pref_lab_title (5571091610359629423) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls (3267606522082281367) -->
+ <skip />
+ <!-- no translation found for pref_lab_quick_controls_summary (1564546156544675707) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage (7597766876952506909) -->
+ <skip />
+ <!-- no translation found for pref_lab_most_visited_homepage_summary (4132511544800457513) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search (1119176077760723740) -->
+ <skip />
+ <!-- no translation found for pref_use_instant_search_summary (839320474961917522) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen (8173609016657987973) -->
+ <skip />
+ <!-- no translation found for pref_lab_fullscreen_summary (6853711692160711419) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher (9063310468293037499) -->
+ <skip />
+ <!-- no translation found for pref_enable_useragent_switcher_summary (1782363693543953474) -->
+ <skip />
+ <!-- no translation found for help_useragent_switcher (123586256526014375) -->
+ <skip />
+ <!-- no translation found for browserFrameNetworkErrorLabel (126892350904924893) -->
+ <skip />
+ <!-- no translation found for browserFrameFileErrorLabel (8063691502792670367) -->
+ <skip />
+ <!-- no translation found for browserFrameFormResubmitLabel (2685923472682180360) -->
+ <skip />
+ <string name="browserFrameFormResubmitMessage" msgid="2752182215695632138">"Ikhasi ozama ukulibuka liqukethe idatha esithunyelwe kakade (\"POSTDATA\"). Uma ufuna ukuthumela futhi idatha, noma isiphi isenzo nokwakheka ekhisini okwenziwayo (njengokusesha noma ukuthenga uxhumeke kwi-inthanethi ) kuzophindwa."</string>
+ <!-- no translation found for loadSuspendedTitle (675991625288706944) -->
+ <skip />
+ <string name="loadSuspended" msgid="3133656588880851273">"Isiphequluli asikwazi ukuhlohla leli khasi ngoba alukho uxhumano lwe-inthanethi"</string>
+ <!-- no translation found for clear_history (5998307092715979619) -->
+ <skip />
+ <string name="browser_history" msgid="1038987118290272525">"Amakhasi asanda kuvakashelwa"</string>
+ <!-- no translation found for empty_history (8738772352308207274) -->
+ <skip />
+ <string name="add_new_bookmark" msgid="8086367791400349049">"Engeza ibhukimakhi..."</string>
+ <string name="add_bookmark_short" msgid="3783984330998103735">"Engeza"</string>
+ <string name="search_hint" msgid="4647356319916631820">"Sesha noma thayipha i-URL"</string>
+ <!-- no translation found for search_button_text (5235226933877634410) -->
+ <skip />
+ <string name="search_settings_description" msgid="1422401062529014107">"Amabhukimakhi nomlando wewebhu."</string>
+ <!-- no translation found for attention (3473639060042811244) -->
+ <skip />
+ <string name="popup_window_attempt" msgid="2673111696288657989">"Le sayithi izama ukuvula iwindi elingugaxekile"</string>
+ <!-- no translation found for allow (1157313689171991335) -->
+ <skip />
+ <!-- no translation found for block (9172175889884707800) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_title (5175503564948906442) -->
+ <skip />
+ <!-- no translation found for too_many_windows_dialog_message (1398571800233959583) -->
+ <skip />
+ <!-- no translation found for too_many_subwindows_dialog_title (3805453941587725944) -->
+ <skip />
+ <string name="too_many_subwindows_dialog_message" msgid="5827289829907966657">"Ayikwazanga ukuvula iwindi elingagaxekile ngoba elilodwa kuphela elingavulwa nganoma isiphi isikhathi."</string>
+ <!-- no translation found for download_title (2122874021047565594) -->
+ <skip />
+ <!-- no translation found for download_unknown_filename (4013465542563652175) -->
+ <skip />
+ <!-- no translation found for download_menu_open (4888327480367757513) -->
+ <skip />
+ <!-- no translation found for download_menu_clear (6264454531553418124) -->
+ <skip />
+ <string name="download_menu_delete" msgid="8815502136393894148">"Susa"</string>
+ <!-- no translation found for download_menu_cancel (2545333007601851574) -->
+ <skip />
+ <!-- no translation found for download_menu_cancel_all (2136550823151999166) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_title (8909108500262799748) -->
+ <skip />
+ <!-- no translation found for download_cancel_dlg_msg (6285389170052357797) -->
+ <skip />
+ <string name="download_delete_file" msgid="5330036497843073249">"Ifayela izosuswa"</string>
+ <!-- no translation found for download_file_error_dlg_title (2693630283595384874) -->
+ <skip />
+ <string name="download_file_error_dlg_msg" msgid="5156405410324072471">"<xliff:g id="FILENAME">%s</xliff:g> ayikwazanga ukulandwa."\n"Khulula isikhala efonini yakho bese uzama futhi."</string>
+ <!-- no translation found for download_failed_generic_dlg_title (6106781095337833391) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (56777245081568508) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_title (605904452159416792) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (3144652102051031721) -->
+ <skip />
+ <!-- no translation found for download_no_sdcard_dlg_msg (2616399456116301518) -->
+ <skip />
+ <!-- outdated translation 6877712666046917741 --> <string name="download_sdcard_busy_dlg_title" product="nosdcard" msgid="8081445664689818973">"Ikhadi le-SD alitholakali"</string>
+ <string name="download_sdcard_busy_dlg_title" product="default" msgid="6877712666046917741">"Ikhadi le-SD alitholakali"</string>
+ <!-- outdated translation 3473883538192835204 --> <string name="download_sdcard_busy_dlg_msg" product="nosdcard" msgid="3979329954835690147">"Ikhadi le-SD limatasa. Ukuvumela ukulanda, khetha \"Vala ukulondoloza nge-USB\" kwisaziso."</string>
+ <string name="download_sdcard_busy_dlg_msg" product="default" msgid="3473883538192835204">"Ikhadi le-SD limatasa. Ukuvumela ukulanda, khetha \"Vala ukulondoloza nge-USB\" kwisaziso."</string>
+ <!-- no translation found for cannot_download (8150552478556798780) -->
+ <skip />
+ <string name="download_no_application_title" msgid="1286056729168874295">"Ayikwazi ukuvula ifayela"</string>
+ <!-- no translation found for retry (1835923075542266721) -->
+ <skip />
+ <!-- no translation found for no_downloads (3947445710685021498) -->
+ <skip />
+ <!-- no translation found for download_error (413496839831257187) -->
+ <skip />
+ <!-- no translation found for download_success (2279041638155595203) -->
+ <skip />
+ <!-- no translation found for download_running (2622942231322015059) -->
+ <skip />
+ <!-- no translation found for download_pending (2599683668575349559) -->
+ <skip />
+ <!-- no translation found for download_pending_network (6548714525679461053) -->
+ <skip />
+ <!-- no translation found for download_running_paused (6418029352085656495) -->
+ <skip />
+ <!-- no translation found for download_canceled (6057083743144492515) -->
+ <skip />
+ <string name="download_not_acceptable" msgid="313769696131563652">"Ayikwazi ukulanda. Okuqukethwe akusekelwe kule foni."</string>
+ <!-- no translation found for download_file_error (1206648050615176113) -->
+ <skip />
+ <!-- no translation found for download_length_required (9038605488460437406) -->
+ <skip />
+ <!-- no translation found for download_precondition_failed (8327584102874295580) -->
+ <skip />
+ <string name="search_the_web" msgid="6046130189241962337">"Sesha iwebhu"</string>
+ <string name="webstorage_outofspace_notification_title" msgid="1160474608059771788">"Ukulondoloza isiphequluli kugcwele"</string>
+ <string name="webstorage_outofspace_notification_text" msgid="7341075135051829692">"Qhafaza ukukhulula isikhala."</string>
+ <string name="webstorage_clear_data_title" msgid="689484577124333977">"Sula idatha elondoloziwe"</string>
+ <string name="webstorage_clear_data_dialog_title" msgid="345457466368974706">"Sula idatha elondoloziwe"</string>
+ <string name="webstorage_clear_data_dialog_message" msgid="6678281256970470125">"Yonke idatha egcinwe yile webhusayithi izosuswa."</string>
+ <string name="webstorage_clear_data_dialog_ok_button" msgid="2516563534211898636">"Sula konke"</string>
+ <string name="webstorage_clear_data_dialog_cancel_button" msgid="2028867751958942762">"Khansela"</string>
+ <string name="webstorage_origin_summary_mb_stored" msgid="1985885826292236210">"I-MB igcinwe efonini yakho"</string>
+ <string name="loading_video" msgid="4887871585216091096">"Ilayisha ividiyo"</string>
+ <string name="geolocation_permissions_prompt_message" msgid="356796102004052471">"<xliff:g id="WEBSITE_ORIGIN">%s</xliff:g> ifuna ukwazi indawo yakho"</string>
+ <string name="geolocation_permissions_prompt_share" msgid="9084486342048347976">"Yabelana ngendawo"</string>
+ <string name="geolocation_permissions_prompt_dont_share" msgid="6303025160237860300">"Nqaba"</string>
+ <string name="geolocation_permissions_prompt_remember" msgid="3118526300707348308">"Khumbula okukhethwayo"</string>
+ <string name="geolocation_permissions_prompt_toast_allowed" msgid="987286072035125498">"Lesayithi iyakwazi ukufinyelela indawo yakho. Shintsha lokhu kokuthi Izilungiselelo -> Izilungiselelo zewebhusayithi"</string>
+ <string name="geolocation_permissions_prompt_toast_disallowed" msgid="7695100950212692515">"Lesayithi ayikwazi ukufinyelela indawo yakho. Shintsha lokhu kokuthi Izilungiselelo -> Izilungiselelo zewebhusayithi"</string>
+ <string name="geolocation_settings_page_title" msgid="1745477985097536528">"Sula ukufinyelela indawo"</string>
+ <string name="geolocation_settings_page_summary_allowed" msgid="9180251524290811398">"Le sayithi okwamanje ingafinyelela kundawo yakho"</string>
+ <string name="geolocation_settings_page_summary_not_allowed" msgid="4589649082203102544">"Le sayithi ayikwazi okwamanje ukufinyelela kundawo yakho"</string>
+ <string name="geolocation_settings_page_dialog_title" msgid="1549842043381347668">"Sula ukufinyelela indawo"</string>
+ <string name="geolocation_settings_page_dialog_message" msgid="7586671987576403993">"Ukufinyelela indawo yalewebhusayithi kuzosulwa."</string>
+ <string name="geolocation_settings_page_dialog_ok_button" msgid="4789434178048077287">"Sula ukufinyelela"</string>
+ <string name="geolocation_settings_page_dialog_cancel_button" msgid="7941036504673409747">"Khansela"</string>
+ <string name="website_settings_clear_all" msgid="8739804325997655980">"Sula konke"</string>
+ <string name="website_settings_clear_all_dialog_title" msgid="7791826325122461718">"Sula zonke izilungiselelo zewebhusayithi?"</string>
+ <string name="website_settings_clear_all_dialog_message" msgid="6150502090601476333">"Yonke idatha yewebhusayithi nezimvume zendawo kuzosuswa"</string>
+ <string name="website_settings_clear_all_dialog_ok_button" msgid="6401582240627669431">"Susa yonke idatha"</string>
+ <string name="website_settings_clear_all_dialog_cancel_button" msgid="1896757051856611674">"Khansela"</string>
+ <string name="progress_dialog_setting_wallpaper" msgid="4871900779338536674">"Ihlela iphephadonga..."</string>
+ <string name="defaultBookmarksUpButton" msgid="2303951020715704735">"Amabhukimakhi"</string>
+ <string name="empty_bookmarks_folder" msgid="7843361614634930942">"Awekho amabhukimakhi"</string>
+ <string name="rlz_access_point" msgid="7165847807377650632">"Y1"</string>
+ <!-- no translation found for account_chooser_dialog_title (3314204833188808194) -->
+ <!-- no translation found for account_chooser_dialog_title (4833571985009544332) -->
+ <skip />
+ <string name="import_bookmarks_dialog_title" msgid="3325557652271172128">"Vumelanisa nge-akhawunti ye-Google"</string>
+ <!-- outdated translation 2187665745413495303 --> <string name="import_bookmarks_dialog_description" msgid="1942452375564381488">"Amabhukimakhi akho e-Android awahlobene ne-akhawunti ye-Google"</string>
+ <!-- no translation found for import_bookmarks_dialog_select_add_account (3102882579089291099) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_delete_select_account (5192284761080626386) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_delete (8854001080444749211) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_confirm_add (5433677293195372675) -->
+ <skip />
+ <!-- outdated translation 8105572409059113340 --> <string name="import_bookmarks_dialog_remove" msgid="5984607822851800902">"Khipha amabhukimakhi akho e-Android"</string>
+ <!-- no translation found for import_bookmarks_wizard_next (7578143961884352676) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_previous (8551440353688257031) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_cancel (4936061122806506634) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_wizard_done (1446247092194489191) -->
+ <skip />
+ <!-- no translation found for import_bookmarks_dialog_add (7552306756868669353) -->
+ <skip />
+ <string name="import_bookmarks_dialog_import" msgid="6933613853573899218">"Yengeza amabhukimakhi akho e-Android kumabhukimakhi e-<xliff:g id="GOOGLE_ACCOUNT">%s</xliff:g>"</string>
+ <!-- no translation found for menu_share_url (5851814357333739700) -->
+ <skip />
+ <!-- no translation found for max_tabs_warning (4122034303809457570) -->
+ <skip />
+ <!-- no translation found for instant_search_label (8769284297650716935) -->
+ <skip />
+ <!-- no translation found for recover_title (8095611702406163360) -->
+ <skip />
+ <!-- no translation found for recover_prompt (5526783279696786755) -->
+ <skip />
+ <!-- no translation found for recover_yes (5837971910598069183) -->
+ <skip />
+ <!-- no translation found for recover_no (3121030267940592611) -->
+ <skip />
+ <!-- no translation found for preview (1470306351083271066) -->
+ <skip />
+ <!-- no translation found for local_bookmarks (533816851415228520) -->
+ <skip />
+</resources>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index 55f8242..6217de1 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -13,5 +13,4 @@
<resources
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<bool name="isTablet">false</bool>
- <bool name="hide_nav_buttons">true</bool>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 6a7c578..322a80a 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,4 +36,6 @@
<color name="qcMenuBackground">#C0000000</color>
<color name="qc_normal">#C02447B2</color>
<color name="qc_selected">#D0102052</color>
+ <color name="tabViewTitleBackground">#D0000000</color>
+ <color name="navtab_bg">#80606060</color>
</resources>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index 1d993f8..dbb0c60 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -30,21 +30,21 @@
<dimen name="widgetItemMinHeight">48dip</dimen>
<dimen name="favicon_size">16dip</dimen>
<dimen name="favicon_padded_size">20dip</dimen>
- <dimen name="qc_radius_start">50dip</dimen>
- <dimen name="qc_radius_increment">70dip</dimen>
- <dimen name="qc_slop">15dip</dimen>
+ <dimen name="qc_radius_start">30dip</dimen>
+ <dimen name="qc_radius_increment">60dip</dimen>
+ <dimen name="qc_slop">10dip</dimen>
<dimen name="qc_touch_offset">15dip</dimen>
<dimen name="qc_tab_title_height">30dip</dimen>
- <dimen name="qc_thumb_width">240dip</dimen>
- <dimen name="qc_thumb_height">160dip</dimen>
- <dimen name="qc_item_size">48dip</dimen>
+ <dimen name="qc_thumb_width">160dip</dimen>
+ <dimen name="qc_thumb_height">120dip</dimen>
+ <dimen name="qc_item_size">40dip</dimen>
<dimen name="bookmark_widget_thumb_size">32dip</dimen>
<dimen name="bookmark_widget_favicon_size">26dip</dimen>
- <!-- For the most visited page -->
- <dimen name="mv_max_width">830dp</dimen>
- <dimen name="mv_item_width">96dp</dimen>
- <dimen name="mv_item_width_portrait">96dp</dimen>
- <dimen name="mv_border_width">3dp</dimen>
+ <!-- For the most visited page (we use px as these are adjusted by the browser) -->
+ <dimen name="mv_max_width">450px</dimen>
+ <dimen name="mv_item_width">80px</dimen>
+ <dimen name="mv_item_width_portrait">80px</dimen>
+ <dimen name="mv_border_width">2px</dimen>
<dimen name="tab_padding_top">12dp</dimen>
<dimen name="tab_first_padding_left">12dp</dimen>
<dimen name="list_favicon_padding">5dip</dimen>
@@ -55,12 +55,22 @@
<dimen name="widgetVerticalSpacing">12dip</dimen>
<!-- For the combined Bookmarks History view -->
<dimen name="combo_paddingTop">10dip</dimen>
- <dimen name="combo_paddingLeftRight">16dip</dimen>
- <dimen name="combo_horizontalSpacing">8dip</dimen>
+ <dimen name="combo_paddingLeftRight">0dip</dimen>
+ <dimen name="combo_horizontalSpacing">6dip</dimen>
+ <dimen name="combo_rowPadding">0dip</dimen>
+ <dimen name="tab_view_thumbnail_height">76dip</dimen>
<!-- Preference activity side margins -->
<dimen name="preference_screen_side_margin">0dp</dimen>
<!-- Preference activity side margins negative-->
<dimen name="preference_screen_side_margin_negative">0dp</dimen>
<!-- Preference widget area width (to the left of the text) -->
<dimen name="preference_widget_width">56dp</dimen>
+ <dimen name="nav_tab_spacing">8dp</dimen>
+ <dimen name="menu_width">240dip</dimen>
+ <dimen name="toolbar_height">52dip</dimen>
+ <dimen name="tab_capture_size">160dp</dimen>
+ <dimen name="nav_tab_width">280dip</dimen>
+ <dimen name="nav_tab_height">280dip</dimen>
+ <dimen name="nav_tab_text_normal">18sp</dimen>
+ <dimen name="nav_tab_text_small">14sp</dimen>
</resources>
diff --git a/res/layout-sw600dp/browser_add_bookmark.xml b/res/values/ids.xml
similarity index 69%
copy from res/layout-sw600dp/browser_add_bookmark.xml
copy to res/values/ids.xml
index 14edecf..d6b74bd 100644
--- a/res/layout-sw600dp/browser_add_bookmark.xml
+++ b/res/values/ids.xml
@@ -14,12 +14,9 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/add_bookmark_width"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
-
- <include layout="@layout/browser_add_bookmark_content" />
-
-</LinearLayout>
+<resources>
+ <!-- IDs for BookmarkExpandableGridView -->
+ <item type="id" name="group_position" />
+ <item type="id" name="child_position" />
+ <item type="id" name="child_id" />
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e754ea9..e51538c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -129,6 +129,8 @@
<string name="do_not_save">Cancel</string>
<!-- Field label in Bookmark dialog box: refers to URL of the page to bookmark -->
<string name="location">Address</string>
+ <!-- Field label in Bookmark dialog box: refers to the account to save the bookmark to -->
+ <string name="account">Account</string>
<!-- Field label in Bookmark dialog box: refers to the folder in which to save the bookmark -->
<string name="containing_folder">Add to</string>
<!-- Default name for a new folder and label for a button that allows the user to create a new folder
@@ -233,6 +235,9 @@
<string name="copy_page_url">Copy page url</string>
<!-- Menu item -->
<string name="share_page">Share page</string>
+ <!-- Menu item to freeze a tab. This will make a view-only
+ snapshot of the page in a new tab. [CHAR LIMIT=50] -->
+ <string name="menu_freeze_tab">Freeze tab</string>
<!-- Menu item for saving a page. [CHAR LIMIT=30] -->
<string name="menu_save_webarchive">Save page</string>
<!-- Toast informing the user that the page has been saved. [CHAR LIMIT=50] -->
@@ -384,9 +389,11 @@
<!-- Message shown during auto login [CHAR-LIMIT=none] -->
<string name="pref_autologin_progress">Signing into Google sites using <xliff:g>%s</xliff:g></string>
<!-- Auto-login bar description [CHAR-LIMIT=40] -->
- <string name="autologin_bar_text">Automatic sign-in is available.</string>
+ <string name="autologin_bar_text">Sign in as</string>
<!-- Login button [CHAR-LIMIT=10] -->
<string name="autologin_bar_login_text">Login</string>
+ <!-- Hide button [CHAR-LIMIT=10] -->
+ <string name="autologin_bar_hide_text">Hide</string>
<!-- Login failure text [CHAR-LIMIT=25] -->
<string name="autologin_bar_error">Login failed.</string>
@@ -523,6 +530,12 @@
<item><xliff:g>LARGER</xliff:g></item>
<item><xliff:g>LARGEST</xliff:g></item>
</string-array>
+ <!-- Label for minimum font size [CHAR LIMIT=30] -->
+ <string name="pref_min_font_size">Minimum font size</string>
+ <!-- Label for whether or not to force-enable user scalablity (aka, zoom) [CHAR LIMIT=30] -->
+ <string name="pref_force_userscalable">Force enable zoom</string>
+ <!-- Summary for whether or not to force-enable user scalablity (aka, zoom) [CHAR LIMIT=30] -->
+ <string name="pref_force_userscalable_summary">Whether or not to override a website\'s request to control zoom behavior</string>
<!-- Settings label -->
<string name="pref_default_zoom">Default zoom</string>
<!-- Settings default zoom options; appear in default zoom dialog box -->
@@ -586,6 +599,7 @@
<item>iPhone</item>
<item>iPad</item>
<item>Froyo-N1</item>
+ <item>Honeycomb-Xoom</item>
</string-array>
<!-- Do not tranlsate. Development option -->
<string-array name="pref_development_ua_values" translatable="false">
@@ -594,6 +608,7 @@
<item>2</item>
<item>3</item>
<item>4</item>
+ <item>5</item>
</string-array>
<string name="pref_development_error_console" translatable="false">Show JavaScript Console</string>
<!-- Settings screen, setting option name -->
@@ -625,6 +640,8 @@
<item>EUC-KR</item>
</string-array>
<string name="pref_default_text_encoding_default" translatable="false">Latin-1</string>
+ <!-- Title for accessibility settings [CHAR LIMIT=25] -->
+ <string name="pref_accessibility_title">Accessibility</string>
<!-- Title for lab settings [CHAR LIMIT=25] -->
<string name="pref_lab_title">Labs</string>
<!-- Title for lab quick controls feature [CHAR LIMIT=40] -->
@@ -643,6 +660,18 @@
<string name="pref_use_instant_search_summary">
Use Google Instant when you use Google Search, to show results as you
type (this can increase data use).</string>
+ <!-- Title for the fullscreen lab feature [CHAR LIMIT=40] -->
+ <string name="pref_lab_fullscreen">Fullscreen</string>
+ <!-- Summary for the fullscreen lab feature [CHAR LIMIT=120] -->
+ <string name="pref_lab_fullscreen_summary">
+ Use fullscreen mode to hide the status bar.</string>
+ <!-- Title for the useragent switcher lab feature [CHAR LIMIT=40] -->
+ <string name="pref_enable_useragent_switcher">Useragent Switcher</string>
+ <!-- Summary for the useragent switcher lab feature [CHAR LIMIT=120] -->
+ <string name="pref_enable_useragent_switcher_summary">Toggle between the tablet and desktop versions of a site</string>
+ <!-- Text explaining how to use the useragent switcher lab feature [CHAR LIMIT=none] -->
+ <string name="help_useragent_switcher">Tap on the Android or laptop icon to toggle between the tablet and desktop versions of a site.</string>
+
<!-- Title for a dialog displayed when the browser has a data connectivity
problem -->
<string name="browserFrameNetworkErrorLabel">Data connectivity problem</string>
@@ -975,4 +1004,16 @@
the search engines list (Preferences->Advanced->Set search engine
[CHAR LIMIT=80] -->
<string name="instant_search_label">Google with Instant (Labs)</string>
+ <!-- Recover tabs after a crash dialog title [CHAR LIMIT=32] -->
+ <string name="recover_title">Restore windows?</string>
+ <!-- Recover tabs after a crash dialog prompt [CHAR LIMIT=none] -->
+ <string name="recover_prompt">Browser appears to have crashed. Would you like to restore your windows from last time?</string>
+ <!-- Yes, recover windows from last time [CHAR LIMIT=10] -->
+ <string name="recover_yes">Yes</string>
+ <!-- No, don't recover windows from last time [CHAR LIMIT=10] -->
+ <string name="recover_no">No</string>
+ <!-- Font size preview label [CHAR LIMIT=30] -->
+ <string name="preview">Preview:</string>
+ <!-- Name for the user's unsynced, local bookmarks [CHAR LIMIT=50] -->
+ <string name="local_bookmarks">Local</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8d222f4..1b77509 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -23,6 +23,7 @@
<item name="android:colorBackground">#FFFFFFFF</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowNoTitle">false</item>
+ <item name="android:windowActionBarOverlay">true</item>
<item name="android:actionBarStyle">@style/ActionBarStyle</item>
<item name="android:actionButtonStyle">@style/ActionButton</item>
</style>
@@ -68,7 +69,7 @@
<item name="android:windowEnterAnimation">@anim/title_bar_enter</item>
<item name="android:windowExitAnimation">@anim/title_bar_exit</item>
</style>
- <style name="HoloIcon">
+ <style name="HoloIcon">
<item name="android:layout_marginLeft">16dip</item>
</style>
<style name="HoloButton">
diff --git a/res/xml-sw600dp/lab_preferences.xml b/res/xml-sw600dp/lab_preferences.xml
new file mode 100644
index 0000000..c858c38
--- /dev/null
+++ b/res/xml-sw600dp/lab_preferences.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <CheckBoxPreference
+ android:key="enable_quick_controls"
+ android:defaultValue="false"
+ android:title="@string/pref_lab_quick_controls"
+ android:summary="@string/pref_lab_quick_controls_summary" />
+
+ <CheckBoxPreference
+ android:key="use_most_visited_homepage"
+ android:defaultValue="false"
+ android:title="@string/pref_lab_most_visited_homepage"
+ android:summary="@string/pref_lab_most_visited_homepage_summary" />
+
+ <CheckBoxPreference
+ android:key="use_instant_search"
+ android:defaultValue="false"
+ android:title="@string/pref_use_instant_search"
+ android:summary="@string/pref_use_instant_search_summary" />
+
+ <CheckBoxPreference
+ android:key="enable_useragent_switcher"
+ android:defaultValue="false"
+ android:title="@string/pref_enable_useragent_switcher"
+ android:summary="@string/pref_enable_useragent_switcher_summary" />
+</PreferenceScreen>
diff --git a/res/xml/accessibility_preferences.xml b/res/xml/accessibility_preferences.xml
new file mode 100644
index 0000000..799d0e2
--- /dev/null
+++ b/res/xml/accessibility_preferences.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <com.android.browser.preferences.WebViewPreview />
+
+ <ListPreference
+ android:key="text_size"
+ android:title="@string/pref_text_size"
+ android:defaultValue="NORMAL"
+ android:entries="@array/pref_text_size_choices"
+ android:entryValues="@array/pref_text_size_values"
+ android:dialogTitle="@string/pref_text_size_dialogtitle" />
+
+ <com.android.browser.preferences.MinFontSizePreference
+ android:key="min_font_size"
+ android:title="@string/pref_min_font_size"
+ android:defaultValue="1" />
+
+ <CheckBoxPreference android:key="force_userscalable"
+ android:title="@string/pref_force_userscalable"
+ android:summary="@string/pref_force_userscalable_summary"
+ android:defaultValue="false" />
+
+</PreferenceScreen>
diff --git a/res/xml/advanced_preferences.xml b/res/xml/advanced_preferences.xml
index 3264d22..4a2823e 100644
--- a/res/xml/advanced_preferences.xml
+++ b/res/xml/advanced_preferences.xml
@@ -50,13 +50,6 @@
android:summary="@string/pref_extras_website_settings_summary" />
<PreferenceCategory android:title="@string/pref_content_title">
- <ListPreference
- android:key="text_size"
- android:title="@string/pref_text_size"
- android:defaultValue="NORMAL"
- android:entries="@array/pref_text_size_choices"
- android:entryValues="@array/pref_text_size_values"
- android:dialogTitle="@string/pref_text_size_dialogtitle" />
<ListPreference
android:key="default_zoom"
diff --git a/res/xml/bookmarkthumbnailwidget_info.xml b/res/xml/bookmarkthumbnailwidget_info.xml
index 65497cd..e98e3f7 100644
--- a/res/xml/bookmarkthumbnailwidget_info.xml
+++ b/res/xml/bookmarkthumbnailwidget_info.xml
@@ -22,5 +22,6 @@
android:updatePeriodMillis="0"
android:previewImage="@drawable/browser_widget_preview"
android:initialLayout="@layout/bookmarkthumbnailwidget"
- android:resizeMode="vertical">
+ android:resizeMode="vertical"
+ android:configure="com.android.browser.widget.BookmarkWidgetConfigure">
</appwidget-provider>
diff --git a/res/xml/debug_preferences.xml b/res/xml/debug_preferences.xml
index 50d4c14..5126b0d 100644
--- a/res/xml/debug_preferences.xml
+++ b/res/xml/debug_preferences.xml
@@ -29,4 +29,51 @@
android:entryValues="@array/pref_development_ua_values"
android:defaultValue="0"/>
+ <!-- The javascript console is enabled by default when the user has
+ also enabled debug mode by navigating to about:debug. -->
+ <CheckBoxPreference
+ android:key="enable_visual_indicator"
+ android:defaultValue="false"
+ android:title="@string/pref_development_visual_indicator" />
+
+ <CheckBoxPreference
+ android:key="javascript_console"
+ android:defaultValue="true"
+ android:title="@string/pref_development_error_console" />
+
+ <CheckBoxPreference
+ android:key="small_screen"
+ android:defaultValue="false"
+ android:title="@string/pref_development_single_column_rendering" />
+
+ <CheckBoxPreference
+ android:key="wide_viewport"
+ android:defaultValue="true"
+ android:title="@string/pref_development_viewport" />
+
+ <CheckBoxPreference
+ android:key="normal_layout"
+ android:defaultValue="false"
+ android:title="@string/pref_development_normal_rendering" />
+
+ <CheckBoxPreference
+ android:key="enable_tracing"
+ android:defaultValue="false"
+ android:title="@string/pref_development_trace" />
+
+ <CheckBoxPreference
+ android:key="enable_light_touch"
+ android:defaultValue="false"
+ android:title="Enable light touch" />
+
+ <CheckBoxPreference
+ android:key="enable_nav_dump"
+ android:defaultValue="false"
+ android:title="@string/pref_development_nav_dump" />
+
+ <EditTextPreference
+ android:key="js_engine_flags"
+ android:title="@string/js_engine_flags"
+ android:singleLine="true" />
+
</PreferenceScreen>
diff --git a/res/xml/general_preferences.xml b/res/xml/general_preferences.xml
index 92b1f2a..7b26307 100644
--- a/res/xml/general_preferences.xml
+++ b/res/xml/general_preferences.xml
@@ -22,13 +22,6 @@
android:hint="@string/http"
android:inputType="textUri|textMultiLine" />
- <PreferenceCategory android:title="@string/pref_general_sync_title">
- <Preference android:key="sync_with_chrome"
- android:title="@string/pref_personal_sync_with_chrome"
- android:summary="@string/pref_personal_sync_with_chrome_summary"
- />
- </PreferenceCategory>
-
<PreferenceCategory android:title="@string/pref_general_autofill_title">
<CheckBoxPreference android:key="autofill_enabled"
android:title="@string/pref_autofill_enabled"
diff --git a/res/xml/hidden_debug_preferences.xml b/res/xml/hidden_debug_preferences.xml
deleted file mode 100644
index 661d9de..0000000
--- a/res/xml/hidden_debug_preferences.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android" >
-
- <!-- The javascript console is enabled by default when the user has
- also enabled debug mode by navigating to about:debug. -->
- <CheckBoxPreference
- android:key="enable_visual_indicator"
- android:defaultValue="false"
- android:title="@string/pref_development_visual_indicator" />
-
- <CheckBoxPreference
- android:key="javascript_console"
- android:defaultValue="true"
- android:title="@string/pref_development_error_console" />
-
- <CheckBoxPreference
- android:key="small_screen"
- android:defaultValue="false"
- android:title="@string/pref_development_single_column_rendering" />
-
- <CheckBoxPreference
- android:key="wide_viewport"
- android:defaultValue="true"
- android:title="@string/pref_development_viewport" />
-
- <CheckBoxPreference
- android:key="normal_layout"
- android:defaultValue="false"
- android:title="@string/pref_development_normal_rendering" />
-
- <CheckBoxPreference
- android:key="enable_tracing"
- android:defaultValue="false"
- android:title="@string/pref_development_trace" />
-
- <CheckBoxPreference
- android:key="enable_light_touch"
- android:defaultValue="false"
- android:title="Enable light touch" />
-
- <CheckBoxPreference
- android:key="enable_nav_dump"
- android:defaultValue="false"
- android:title="@string/pref_development_nav_dump" />
-
- <EditTextPreference
- android:key="js_engine_flags"
- android:title="@string/js_engine_flags"
- android:singleLine="true" />
-
-</PreferenceScreen>
diff --git a/res/xml/lab_preferences.xml b/res/xml/lab_preferences.xml
index 87383b0..ee00463 100644
--- a/res/xml/lab_preferences.xml
+++ b/res/xml/lab_preferences.xml
@@ -16,22 +16,19 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" >
-
<CheckBoxPreference
android:key="enable_quick_controls"
android:defaultValue="false"
android:title="@string/pref_lab_quick_controls"
android:summary="@string/pref_lab_quick_controls_summary" />
-
<CheckBoxPreference
android:key="use_most_visited_homepage"
android:defaultValue="false"
android:title="@string/pref_lab_most_visited_homepage"
android:summary="@string/pref_lab_most_visited_homepage_summary" />
-
<CheckBoxPreference
- android:key="use_instant_search"
+ android:key="fullscreen"
android:defaultValue="false"
- android:title="@string/pref_use_instant_search"
- android:summary="@string/pref_use_instant_search_summary" />
+ android:title="@string/pref_lab_fullscreen"
+ android:summary="@string/pref_lab_fullscreen_summary" />
</PreferenceScreen>
diff --git a/res/xml/preference_headers.xml b/res/xml/preference_headers.xml
index cdf259c..e58b90a 100644
--- a/res/xml/preference_headers.xml
+++ b/res/xml/preference_headers.xml
@@ -24,6 +24,10 @@
android:title="@string/pref_privacy_security_title"
/>
+ <header android:fragment="com.android.browser.preferences.AccessibilityPreferencesFragment"
+ android:title="@string/pref_accessibility_title"
+ />
+
<header android:fragment="com.android.browser.preferences.AdvancedPreferencesFragment"
android:title="@string/pref_extras_title"
/>
diff --git a/src/com/android/browser/AccountsChangedReceiver.java b/src/com/android/browser/AccountsChangedReceiver.java
deleted file mode 100644
index a34180a..0000000
--- a/src/com/android/browser/AccountsChangedReceiver.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.browser.widget.BookmarkThumbnailWidgetProvider;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.provider.BrowserContract;
-
-public class AccountsChangedReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // Validate that the account we are syncing to still exists
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- if (accountType == null || accountName == null) {
- // Not syncing, nothing to do
- return;
- }
- Account[] accounts = AccountManager.get(context).getAccountsByType(accountType);
- for (Account a : accounts) {
- if (accountName.equals(a.name)) {
- // Still have a valid account, sweet
- return;
- }
- }
- // Account deleted - disable sync
- prefs.edit()
- .remove(BrowserBookmarksPage.PREF_ACCOUNT_TYPE)
- .remove(BrowserBookmarksPage.PREF_ACCOUNT_NAME)
- .commit();
- BrowserContract.Settings.setSyncEnabled(context, false);
- for (Account a : accounts) {
- ContentResolver.setSyncAutomatically(a, BrowserContract.AUTHORITY, false);
- ContentResolver.setIsSyncable(a, BrowserContract.AUTHORITY, 0);
- }
- BookmarkThumbnailWidgetProvider.refreshWidgets(context, true);
- }
-
-}
diff --git a/src/com/android/browser/ActiveTabsPage.java b/src/com/android/browser/ActiveTabsPage.java
index 664fd68..0feba9a 100644
--- a/src/com/android/browser/ActiveTabsPage.java
+++ b/src/com/android/browser/ActiveTabsPage.java
@@ -18,62 +18,88 @@
import android.content.Context;
import android.graphics.Bitmap;
-import android.os.Handler;
+import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
-import android.widget.ListView;
import android.widget.TextView;
-public class ActiveTabsPage extends LinearLayout {
+interface OnCloseTab {
+ void onCloseTab(int position);
+}
- private static final String LOGTAG = "TabPicker";
+public class ActiveTabsPage extends LinearLayout implements OnClickListener,
+ OnItemClickListener, OnCloseTab {
- private final LayoutInflater mFactory;
- private final UiController mUiController;
- private final TabControl mControl;
- private final TabsListAdapter mAdapter;
- private final ListView mListView;
+ private Context mContext;
+ private UiController mController;
+ private TabControl mTabControl;
+ private View mNewTab, mNewIncognitoTab;
+ private TabAdapter mAdapter;
+ private AbsListView mTabsList;
- public ActiveTabsPage(Context context, UiController control) {
+ public ActiveTabsPage(Context context, UiController controller) {
super(context);
- mUiController = control;
- mControl = control.getTabControl();
- mFactory = LayoutInflater.from(context);
- mFactory.inflate(R.layout.active_tabs, this);
- mListView = (ListView) findViewById(R.id.list);
- mAdapter = new TabsListAdapter();
- mListView.setAdapter(mAdapter);
- mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- if (mControl.canCreateNewTab()) {
- position -= 2;
- }
- boolean needToAttach = false;
- if (position == -2) {
- // Create a new tab
- mUiController.openTabToHomePage();
- } else if (position == -1) {
- // Create a new incognito tab
- mUiController.openIncognitoTab();
- } else {
- // Open the corresponding tab
- // If the tab is the current one, switchToTab will
- // do nothing and return, so we need to make sure
- // it gets attached back to its mContentView in
- // removeActiveTabPage
- needToAttach = !mUiController.switchToTab(position);
- }
- mUiController.removeActiveTabsPage(needToAttach);
- }
- });
+ mContext = context;
+ mController = controller;
+ mTabControl = mController.getTabControl();
+ setOrientation(VERTICAL);
+ setBackgroundResource(R.drawable.bg_browser);
+ LayoutInflater inflate = LayoutInflater.from(mContext);
+ inflate.inflate(R.layout.active_tabs, this, true);
+ mNewTab = findViewById(R.id.new_tab);
+ mNewIncognitoTab = findViewById(R.id.new_incognito_tab);
+ mNewTab.setOnClickListener(this);
+ mNewIncognitoTab.setOnClickListener(this);
+ int visibility = mTabControl.canCreateNewTab() ? View.VISIBLE : View.GONE;
+ mNewTab.setVisibility(visibility);
+ mNewIncognitoTab.setVisibility(visibility);
+ mTabsList = (AbsListView) findViewById(android.R.id.list);
+ mAdapter = new TabAdapter(mContext, mTabControl);
+ mAdapter.setOnCloseListener(this);
+ mTabsList.setAdapter(mAdapter);
+ mTabsList.setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mNewTab) {
+ mController.openTabToHomePage();
+ } else if (v == mNewIncognitoTab) {
+ mController.openIncognitoTab();
+ }
+ mController.removeActiveTabsPage(false);
+ }
+
+ @Override
+ public void onItemClick(
+ AdapterView<?> parent, View view, int position, long id) {
+ final Tab tab = mTabControl.getTab(position);
+ boolean needToAttach = !mController.switchToTab(tab);
+ mController.removeActiveTabsPage(needToAttach);
+ }
+
+ @Override
+ public void onCloseTab(int position) {
+ Tab tab = mTabControl.getTab(position);
+ if (tab != null) {
+ mController.closeTab(tab);
+ if (mTabControl.getTabCount() == 0) {
+ mController.openTabToHomePage();
+ mController.removeActiveTabsPage(false);
+ } else {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
}
/**
@@ -81,7 +107,7 @@
* the parent to be pressed without being pressed itself. This way the line
* of a tab can be pressed, but the close button itself is not.
*/
- private static class CloseHolder extends ImageView {
+ public static class CloseHolder extends ImageView {
public CloseHolder(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -96,118 +122,79 @@
}
}
- private class TabsListAdapter extends BaseAdapter {
- private boolean mNotified = true;
- private int mReturnedCount;
- private Handler mHandler = new Handler();
+ static class TabAdapter extends BaseAdapter implements OnClickListener {
+ LayoutInflater mInflater;
+ OnCloseTab mCloseListener;
+ TabControl mTabControl;
+
+ TabAdapter(Context context, TabControl tabs) {
+ mInflater = LayoutInflater.from(context);
+ mTabControl = tabs;
+ }
+
+ void setOnCloseListener(OnCloseTab listener) {
+ mCloseListener = listener;
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null) {
+ view = mInflater.inflate(R.layout.tab_view, parent, false);
+ }
+ ImageView favicon = (ImageView) view.findViewById(R.id.favicon);
+ ImageView thumbnail = (ImageView) view.findViewById(R.id.thumb);
+ TextView title = (TextView) view.findViewById(R.id.label);
+ Tab tab = getItem(position);
+
+ String label = tab.getTitle();
+ if (TextUtils.isEmpty(label)) {
+ label = tab.getUrl();
+ }
+ title.setText(label);
+ Bitmap thumbnailBitmap = tab.getScreenshot();
+ if (thumbnailBitmap == null) {
+ thumbnail.setImageResource(R.drawable.browser_thumbnail);
+ } else {
+ thumbnail.setImageBitmap(thumbnailBitmap);
+ }
+ Bitmap faviconBitmap = tab.getFavicon();
+ if (tab.isPrivateBrowsingEnabled()) {
+ favicon.setImageResource(R.drawable.ic_incognito_holo_dark);
+ } else {
+ if (faviconBitmap == null) {
+ favicon.setImageResource(R.drawable.app_web_browser_sm);
+ } else {
+ favicon.setImageBitmap(faviconBitmap);
+ }
+ }
+ View close = view.findViewById(R.id.close);
+ close.setTag(position);
+ close.setOnClickListener(this);
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int position = (Integer) v.getTag();
+ if (mCloseListener != null) {
+ mCloseListener.onCloseTab(position);
+ }
+ }
+
+ @Override
public int getCount() {
- int count = mControl.getTabCount();
- if (mControl.canCreateNewTab()) {
- count += 2;
- }
- // XXX: This is a workaround to be more like a real adapter. Most
- // adapters call notifyDataSetChanged() whenever the internal data
- // has changed. Since TabControl is our internal data, we don't
- // know when that changes.
- //
- // Keep track of the last count we returned and whether we called
- // notifyDataSetChanged(). If we did not initiate a data set
- // change, and the count is different, send the notify and return
- // the old count.
- if (!mNotified && count != mReturnedCount) {
- notifyChange();
- return mReturnedCount;
- }
- mReturnedCount = count;
- mNotified = false;
- return count;
+ return mTabControl.getTabCount();
}
- public Object getItem(int position) {
- return null;
+
+ @Override
+ public Tab getItem(int position) {
+ return mTabControl.getTab(position);
}
+
+ @Override
public long getItemId(int position) {
return position;
}
- public int getViewTypeCount() {
- return 2;
- }
- public int getItemViewType(int position) {
- if (mControl.canCreateNewTab()) {
- position -= 2;
- }
- // Do not recycle the "add new tab" item.
- return position < 0 ? IGNORE_ITEM_VIEW_TYPE : 1;
- }
- public View getView(int position, View convertView, ViewGroup parent) {
- final int tabCount = mControl.getTabCount();
- if (mControl.canCreateNewTab()) {
- position -= 2;
- }
-
- if (convertView == null) {
- if (position == -2) {
- convertView = mFactory.inflate(R.layout.tab_view_add_tab, null);
- } else if (position == -1) {
- convertView = mFactory.inflate(R.layout.tab_view_add_incognito_tab, null);
- } else {
- convertView = mFactory.inflate(R.layout.tab_view, null);
- }
- }
-
- if (position >= 0) {
- TextView title =
- (TextView) convertView.findViewById(R.id.title);
- TextView url = (TextView) convertView.findViewById(R.id.url);
- ImageView favicon =
- (ImageView) convertView.findViewById(R.id.favicon);
- View close = convertView.findViewById(R.id.close);
- Tab tab = mControl.getTab(position);
- if (tab.getWebView() == null) {
- // This means that populatePickerData will have to use the
- // saved state.
- Log.w(LOGTAG, "Tab " + position + " has a null WebView and "
- + (tab.getSavedState() == null ? "null" : "non-null")
- + " saved state ");
- }
- if (tab.getTitle() == null || tab.getTitle().length() == 0) {
- Log.w(LOGTAG, "Tab " + position + " has no title. "
- + "Check above in the Logs to see whether it has a "
- + "null WebView or null WebHistoryItem");
- }
- title.setText(tab.getTitle());
- url.setText(tab.getUrl());
- Bitmap icon = tab.getFavicon();
- if (icon != null) {
- favicon.setImageBitmap(icon);
- } else {
- favicon.setImageResource(R.drawable.app_web_browser_sm);
- }
- final int closePosition = position;
- close.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- mUiController.closeTab(
- mControl.getTab(closePosition));
- if (tabCount == 1) {
- mUiController.openTabToHomePage();
- mUiController.removeActiveTabsPage(false);
- } else {
- mNotified = true;
- notifyDataSetChanged();
- }
- }
- });
- }
- return convertView;
- }
-
- void notifyChange() {
- mHandler.post(new Runnable() {
- public void run() {
- mNotified = true;
- notifyDataSetChanged();
- }
- });
- }
}
}
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 08f9d39..f330cd5 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -16,19 +16,19 @@
package com.android.browser;
-import com.android.browser.provider.BrowserProvider2;
import com.android.browser.addbookmark.FolderSpinner;
import com.android.browser.addbookmark.FolderSpinnerAdapter;
import android.app.Activity;
import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.AsyncTaskLoader;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
-import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -40,8 +40,8 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.preference.PreferenceManager;
import android.provider.BrowserContract;
+import android.provider.BrowserContract.Accounts;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
@@ -53,20 +53,23 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Stack;
public class AddBookmarkPage extends Activity
implements View.OnClickListener, TextView.OnEditorActionListener,
AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>,
- BreadCrumbView.Controller, FolderSpinner.OnSetSelectionListener {
+ BreadCrumbView.Controller, FolderSpinner.OnSetSelectionListener,
+ OnItemSelectedListener {
public static final long DEFAULT_FOLDER_ID = -1;
public static final String TOUCH_ICON_URL = "touch_icon_url";
@@ -83,12 +86,9 @@
private final String LOGTAG = "Bookmarks";
// IDs for the CursorLoaders that are used.
- private final int LOADER_ID_FOLDER_CONTENTS = 0;
- private final int LOADER_ID_ALL_FOLDERS = 1;
- private final int LOADER_ID_FIND_ROOT = 2;
- private final int LOADER_ID_CHECK_FOR_DUPE = 3;
- private final int LOADER_ID_MOST_RECENTLY_SAVED_BOOKMARK = 4;
- private final int LOADER_ID_FIND_FOLDER_BY_ID = 5;
+ private final int LOADER_ID_ACCOUNTS = 0;
+ private final int LOADER_ID_FOLDER_CONTENTS = 1;
+ private final int LOADER_ID_EDIT_INFO = 2;
private EditText mTitle;
private EditText mAddress;
@@ -121,6 +121,9 @@
private View mRemoveLink;
private View mFakeTitleHolder;
private FolderSpinnerAdapter mFolderAdapter;
+ private Spinner mAccountSpinner;
+ private ArrayAdapter<BookmarkAccount> mAccountAdapter;
+
private static class Folder {
String Name;
long Id;
@@ -142,26 +145,16 @@
}
private Uri getUriForFolder(long folder) {
- Uri uri;
- if (folder == mRootFolder) {
- uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
- } else {
- uri = BrowserContract.Bookmarks.buildFolderUri(folder);
- }
- String[] accountInfo = getAccountNameAndType(this);
- if (accountInfo != null) {
- uri = BookmarksLoader.addAccount(uri, accountInfo[1], accountInfo[0]);
- }
- return uri;
+ return BrowserContract.Bookmarks.buildFolderUri(folder);
}
@Override
- public void onTop(int level, Object data) {
+ public void onTop(BreadCrumbView view, int level, Object data) {
if (null == data) return;
Folder folderData = (Folder) data;
long folder = folderData.Id;
LoaderManager manager = getLoaderManager();
- CursorLoader loader = (CursorLoader) ((Loader) manager.getLoader(
+ CursorLoader loader = (CursorLoader) ((Loader<?>) manager.getLoader(
LOADER_ID_FOLDER_CONTENTS));
loader.setUri(getUriForFolder(folder));
loader.forceLoad();
@@ -213,7 +206,7 @@
// editing a folder, 1 otherwise.
mFolder.setSelectionIgnoringSelectionChange(mEditingFolder ? 0 : 1);
} else {
- ((TextView) mFolder.getSelectedView()).setText(folder.Name);
+ mFolderAdapter.setOtherFolderDisplayText(folder.Name);
}
}
} else {
@@ -227,17 +220,15 @@
} else {
Object data = mCrumbs.getTopData();
if (data != null && ((Folder) data).Id == mCurrentFolder) {
- // We are showing the correct folder heirarchy. The
+ // We are showing the correct folder hierarchy. The
// folder selector will say "Other folder..." Change it
// to say the name of the folder once again.
- ((TextView) mFolder.getSelectedView()).setText(((Folder) data).Name);
+ mFolderAdapter.setOtherFolderDisplayText(((Folder) data).Name);
} else {
- // We are not be showing the correct folder heirarchy.
+ // We are not showing the correct folder hierarchy.
// Clear the Crumbs and find the proper folder
- mCrumbs.clear();
setupTopCrumb();
LoaderManager manager = getLoaderManager();
- manager.restartLoader(LOADER_ID_ALL_FOLDERS, null, this);
manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
}
@@ -319,7 +310,6 @@
// and choose a different one, so that we will start from
// the correct place.
LoaderManager manager = getLoaderManager();
- manager.initLoader(LOADER_ID_ALL_FOLDERS, null, this);
manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
break;
default:
@@ -351,11 +341,6 @@
values.put(BrowserContract.Bookmarks.TITLE,
name);
values.put(BrowserContract.Bookmarks.IS_FOLDER, 1);
- String[] accountInfo = getAccountNameAndType(this);
- if (accountInfo != null) {
- values.put(BrowserContract.Bookmarks.ACCOUNT_TYPE, accountInfo[1]);
- values.put(BrowserContract.Bookmarks.ACCOUNT_NAME, accountInfo[0]);
- }
long currentFolder;
Object data = mCrumbs.getTopData();
if (data != null) {
@@ -391,66 +376,78 @@
}
}
+ private LoaderCallbacks<EditBookmarkInfo> mEditInfoLoaderCallbacks =
+ new LoaderCallbacks<EditBookmarkInfo>() {
+
+ @Override
+ public void onLoaderReset(Loader<EditBookmarkInfo> loader) {
+ // Don't care
+ }
+
+ @Override
+ public void onLoadFinished(Loader<EditBookmarkInfo> loader,
+ EditBookmarkInfo info) {
+ boolean setAccount = false;
+ if (info.id != -1) {
+ mEditingExisting = true;
+ showRemoveButton();
+ mFakeTitle.setText(R.string.edit_bookmark);
+ mTitle.setText(info.title);
+ mFolderAdapter.setOtherFolderDisplayText(info.parentTitle);
+ mMap.putLong(BrowserContract.Bookmarks._ID, info.id);
+ setAccount = true;
+ setAccount(info.accountName, info.accountType);
+ mCurrentFolder = info.parentId;
+ onCurrentFolderFound();
+ }
+ // TODO: Detect if lastUsedId is a subfolder of info.id in the
+ // editing folder case. For now, just don't show the last used
+ // folder at all to prevent any chance of the user adding a parent
+ // folder to a child folder
+ if (info.lastUsedId != -1 && info.lastUsedId != info.id
+ && !mEditingFolder) {
+ if (setAccount && info.lastUsedId != mRootFolder
+ && TextUtils.equals(info.lastUsedAccountName, info.accountName)
+ && TextUtils.equals(info.lastUsedAccountType, info.accountType)) {
+ mFolderAdapter.addRecentFolder(info.lastUsedId, info.lastUsedTitle);
+ } else if (!setAccount) {
+ setAccount = true;
+ setAccount(info.lastUsedAccountName, info.lastUsedAccountType);
+ if (info.lastUsedId != mRootFolder) {
+ mFolderAdapter.addRecentFolder(info.lastUsedId,
+ info.lastUsedTitle);
+ }
+ }
+ }
+ if (!setAccount) {
+ mAccountSpinner.setSelection(0);
+ }
+ }
+
+ @Override
+ public Loader<EditBookmarkInfo> onCreateLoader(int id, Bundle args) {
+ return new EditBookmarkInfoLoader(AddBookmarkPage.this, mMap);
+ }
+ };
+
+ void setAccount(String accountName, String accountType) {
+ for (int i = 0; i < mAccountAdapter.getCount(); i++) {
+ BookmarkAccount account = mAccountAdapter.getItem(i);
+ if (TextUtils.equals(account.accountName, accountName)
+ && TextUtils.equals(account.accountType, accountType)) {
+ onRootFolderFound(account.rootFolderId);
+ mAccountSpinner.setSelection(i);
+ return;
+ }
+ }
+ }
+
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection;
switch (id) {
- case LOADER_ID_CHECK_FOR_DUPE:
- projection = new String[] {
- BrowserContract.Bookmarks._ID,
- BrowserContract.Bookmarks.PARENT,
- BrowserContract.Bookmarks.TITLE
- };
- return new CursorLoader(this,
- BookmarkUtils.getBookmarksUri(this),
- projection,
- BrowserContract.Bookmarks.URL + " = ?",
- new String[] { mOriginalUrl },
- null);
- case LOADER_ID_FIND_ROOT:
- String name = args.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME);
- String type = args.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE);
-
- projection = new String[] { BrowserContract.Bookmarks._ID };
- String selection = BrowserContract.ChromeSyncColumns.SERVER_UNIQUE + "=? AND "
- + BrowserContract.Bookmarks.ACCOUNT_NAME + "=? AND "
- + BrowserContract.Bookmarks.ACCOUNT_TYPE + "=?";
- String[] selArgs = new String[] {
- BrowserContract.ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR,
- name,
- type
- };
- return new CursorLoader(this,
- BrowserContract.Bookmarks.CONTENT_URI,
- projection,
- selection,
- selArgs,
- null);
- case LOADER_ID_FIND_FOLDER_BY_ID:
- projection = new String[] {
- BrowserContract.Bookmarks._ID,
- BrowserContract.Bookmarks.TITLE
- };
- return new CursorLoader(this,
- BookmarkUtils.getBookmarksUri(this),
- projection,
- BrowserContract.Bookmarks._ID + " = "
- + args.getLong(BrowserContract.Bookmarks._ID),
- null,
- null);
- case LOADER_ID_ALL_FOLDERS:
- projection = new String[] {
- BrowserContract.Bookmarks._ID,
- BrowserContract.Bookmarks.PARENT,
- BrowserContract.Bookmarks.TITLE,
- BrowserContract.Bookmarks.IS_FOLDER
- };
- return new CursorLoader(this,
- BookmarkUtils.getBookmarksUri(this),
- projection,
- BrowserContract.Bookmarks.IS_FOLDER + " != 0",
- null,
- null);
+ case LOADER_ID_ACCOUNTS:
+ return new AccountsLoader(this);
case LOADER_ID_FOLDER_CONTENTS:
projection = new String[] {
BrowserContract.Bookmarks._ID,
@@ -458,26 +455,25 @@
BrowserContract.Bookmarks.IS_FOLDER
};
String where = BrowserContract.Bookmarks.IS_FOLDER + " != 0";
+ String whereArgs[] = null;
if (mEditingFolder) {
- where += " AND " + BrowserContract.Bookmarks._ID + " != "
- + mMap.getLong(BrowserContract.Bookmarks._ID);
+ where += " AND " + BrowserContract.Bookmarks._ID + " != ?";
+ whereArgs = new String[] { Long.toString(mMap.getLong(
+ BrowserContract.Bookmarks._ID)) };
+ }
+ long currentFolder;
+ Object data = mCrumbs.getTopData();
+ if (data != null) {
+ currentFolder = ((Folder) data).Id;
+ } else {
+ currentFolder = mRootFolder;
}
return new CursorLoader(this,
- getUriForFolder(mCurrentFolder),
+ getUriForFolder(currentFolder),
projection,
where,
- null,
+ whereArgs,
BrowserContract.Bookmarks._ID + " ASC");
- case LOADER_ID_MOST_RECENTLY_SAVED_BOOKMARK:
- projection = new String[] {
- BrowserContract.Bookmarks.PARENT
- };
- return new CursorLoader(this,
- BookmarkUtils.getBookmarksUri(this),
- projection,
- BrowserContract.Bookmarks.IS_FOLDER + " = 0",
- null,
- BrowserContract.Bookmarks.DATE_CREATED + " DESC");
default:
throw new AssertionError("Asking for nonexistant loader!");
}
@@ -486,101 +482,18 @@
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
- case LOADER_ID_CHECK_FOR_DUPE:
- if (cursor != null && cursor.moveToFirst()) {
- // Site is bookmarked.
- mEditingExisting = true;
- showRemoveButton();
- mFakeTitle.setText(R.string.edit_bookmark);
- int index = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks.PARENT);
- mCurrentFolder = cursor.getLong(index);
- index = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks.TITLE);
- String title = cursor.getString(index);
- mTitle.setText(title);
- index = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks._ID);
- long id = cursor.getLong(index);
- mMap.putLong(BrowserContract.Bookmarks._ID, id);
+ case LOADER_ID_ACCOUNTS:
+ mAccountAdapter.clear();
+ while (cursor.moveToNext()) {
+ mAccountAdapter.add(new BookmarkAccount(this, cursor));
}
- onCurrentFolderFound();
- getLoaderManager().destroyLoader(LOADER_ID_CHECK_FOR_DUPE);
- break;
- case LOADER_ID_FIND_ROOT:
- long root;
- if (cursor != null && cursor.moveToFirst()) {
- root = cursor.getLong(0);
- } else {
- root = BrowserProvider2.FIXED_ID_ROOT;
- }
- onRootFolderFound(root);
- getLoaderManager().destroyLoader(LOADER_ID_FIND_ROOT);
+ getLoaderManager().destroyLoader(LOADER_ID_ACCOUNTS);
+ getLoaderManager().restartLoader(LOADER_ID_EDIT_INFO, null,
+ mEditInfoLoaderCallbacks);
break;
case LOADER_ID_FOLDER_CONTENTS:
mAdapter.changeCursor(cursor);
break;
- case LOADER_ID_MOST_RECENTLY_SAVED_BOOKMARK:
- LoaderManager manager = getLoaderManager();
- if (cursor != null && cursor.moveToFirst()) {
- // Find the parent
- long lastUsedFolder = cursor.getLong(0);
- if (lastUsedFolder != mRootFolder
- && lastUsedFolder != mCurrentFolder
- && lastUsedFolder != 0) {
- // Find out the parent's name
- Bundle b = new Bundle();
- b.putLong(BrowserContract.Bookmarks._ID, lastUsedFolder);
- manager.initLoader(LOADER_ID_FIND_FOLDER_BY_ID, b, this);
- }
- }
- manager.destroyLoader(LOADER_ID_MOST_RECENTLY_SAVED_BOOKMARK);
- break;
- case LOADER_ID_FIND_FOLDER_BY_ID:
- if (cursor != null && cursor.moveToFirst()) {
- long id = cursor.getLong(cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks._ID));
- String title = cursor.getString(cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks.TITLE));
- mFolderAdapter.addRecentFolder(id, title);
- }
- getLoaderManager().destroyLoader(LOADER_ID_FIND_FOLDER_BY_ID);
- break;
- case LOADER_ID_ALL_FOLDERS:
- long parent = mCurrentFolder;
- int idIndex = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks._ID);
- int titleIndex = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks.TITLE);
- int parentIndex = cursor.getColumnIndexOrThrow(
- BrowserContract.Bookmarks.PARENT);
- // If the user is editing anything inside the "Other Bookmarks"
- // folder, we need to stop searching up when we reach its parent.
- // Find the root folder
- moveCursorToFolder(cursor, mRootFolder, idIndex);
- // omniparent is the folder which contains root, and therefore
- // also the parent of the "Other Bookmarks" folder.
- long omniparent = cursor.getLong(parentIndex);
- Stack<Folder> folderStack = new Stack<Folder>();
- while ((parent != mRootFolder) && (parent != 0) && (parent != omniparent)) {
- // First, find the folder corresponding to the current
- // folder
- moveCursorToFolder(cursor, parent, idIndex);
- String name = cursor.getString(titleIndex);
- if (parent == mCurrentFolder) {
- ((TextView) mFolder.getSelectedView()).setText(name);
- }
- folderStack.push(new Folder(name, parent));
- parent = cursor.getLong(parentIndex);
- }
- while (!folderStack.isEmpty()) {
- Folder thisFolder = folderStack.pop();
- mCrumbs.pushView(thisFolder.Name, thisFolder);
- }
- getLoaderManager().destroyLoader(LOADER_ID_ALL_FOLDERS);
- break;
- default:
- break;
}
}
@@ -727,7 +640,7 @@
mCancelButton.setOnClickListener(this);
mFolder = (FolderSpinner) findViewById(R.id.folder);
- mFolderAdapter = new FolderSpinnerAdapter(!mEditingFolder);
+ mFolderAdapter = new FolderSpinnerAdapter(this, !mEditingFolder);
mFolder.setAdapter(mFolderAdapter);
mFolder.setOnSetSelectionListener(this);
@@ -759,22 +672,22 @@
mListView.setOnItemClickListener(this);
mListView.addEditText(mFolderNamer);
+ mAccountAdapter = new ArrayAdapter<BookmarkAccount>(this,
+ android.R.layout.simple_spinner_item);
+ mAccountAdapter.setDropDownViewResource(
+ android.R.layout.simple_spinner_dropdown_item);
+ mAccountSpinner = (Spinner) findViewById(R.id.accounts);
+ mAccountSpinner.setAdapter(mAccountAdapter);
+ mAccountSpinner.setOnItemSelectedListener(this);
+
+
mFakeTitleHolder = findViewById(R.id.title_holder);
if (!window.getDecorView().isInTouchMode()) {
mButton.requestFocus();
}
- String[] accountInfo = getAccountNameAndType(this);
- if (accountInfo == null) {
- onRootFolderFound(BrowserProvider2.FIXED_ID_ROOT);
- } else {
- Bundle args = new Bundle();
- args.putString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, accountInfo[0]);
- args.putString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, accountInfo[1]);
- getLoaderManager().initLoader(LOADER_ID_FIND_ROOT, args, this);
- }
-
+ getLoaderManager().restartLoader(LOADER_ID_ACCOUNTS, null, this);
}
private void showRemoveButton() {
@@ -787,22 +700,13 @@
// Called once we have determined which folder is the root folder
private void onRootFolderFound(long root) {
mRootFolder = root;
- if (mCurrentFolder == DEFAULT_FOLDER_ID) {
- mCurrentFolder = mRootFolder;
- }
+ mCurrentFolder = mRootFolder;
setupTopCrumb();
- if (mEditingExisting || TextUtils.isEmpty(mOriginalUrl)
- || !(mMap != null && mMap.getBoolean(CHECK_FOR_DUPE))) {
- onCurrentFolderFound();
- } else {
- // User is attempting to bookmark a site, rather than deliberately
- // editing a bookmark. Rather than let them create a duplicate
- // bookmark, see if the bookmark already exists.
- getLoaderManager().initLoader(LOADER_ID_CHECK_FOR_DUPE, null, this);
- }
+ onCurrentFolderFound();
}
private void setupTopCrumb() {
+ mCrumbs.clear();
String name = getString(R.string.bookmarks);
mTopLevelLabel = (TextView) mCrumbs.pushView(name, false,
new Folder(name, mRootFolder));
@@ -813,19 +717,12 @@
private void onCurrentFolderFound() {
LoaderManager manager = getLoaderManager();
if (mCurrentFolder != mRootFolder) {
- // Find all the folders
- manager.initLoader(LOADER_ID_ALL_FOLDERS, null, this);
// Since we're not in the root folder, change the selection to other
// folder now. The text will get changed once we select the correct
// folder.
mFolder.setSelectionIgnoringSelectionChange(mEditingFolder ? 1 : 2);
} else {
setShowBookmarkIcon(true);
- if (!mEditingExisting) {
- // Find the most recently saved bookmark, so that we can include it in
- // the list of options to save the current bookmark.
- manager.initLoader(LOADER_ID_MOST_RECENTLY_SAVED_BOOKMARK, null, this);
- }
if (!mEditingFolder) {
// Initially the "Bookmarks" folder should be showing, rather than
// the home screen. In the editing folder case, home screen is not
@@ -834,22 +731,7 @@
}
}
// Find the contents of the current folder
- manager.initLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
-}
- /**
- * Get the account name and type of the currently synced account.
- * @param context Context to access preferences.
- * @return null if no account name or type. Otherwise, the result will be
- * an array of two Strings, the accountName and accountType, respectively.
- */
- private String[] getAccountNameAndType(Context context) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
- return null;
- }
- return new String[] { accountName, accountType };
+ manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
}
/**
@@ -1070,6 +952,22 @@
return true;
}
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position,
+ long id) {
+ if (mAccountSpinner == parent) {
+ long root = mAccountAdapter.getItem(position).rootFolderId;
+ if (root != mRootFolder) {
+ onRootFolderFound(root);
+ }
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Don't care
+ }
+
/*
* Class used as a proxy for the InputMethodManager to get to mFolderNamer
*/
@@ -1097,4 +995,162 @@
return view == mEditText;
}
}
+
+ public static class AccountsLoader extends CursorLoader {
+
+ static final String[] PROJECTION = new String[] {
+ Accounts.ACCOUNT_NAME,
+ Accounts.ACCOUNT_TYPE,
+ Accounts.ROOT_ID,
+ };
+
+ static final int COLUMN_INDEX_ACCOUNT_NAME = 0;
+ static final int COLUMN_INDEX_ACCOUNT_TYPE = 1;
+ static final int COLUMN_INDEX_ROOT_ID = 2;
+
+ public AccountsLoader(Context context) {
+ super(context, Accounts.CONTENT_URI, PROJECTION, null, null,
+ Accounts.ACCOUNT_NAME + " ASC");
+ }
+
+ }
+
+ public static class BookmarkAccount {
+
+ private String mLabel;
+ String accountName, accountType;
+ public long rootFolderId;
+
+ public BookmarkAccount(Context context, Cursor cursor) {
+ accountName = cursor.getString(
+ AccountsLoader.COLUMN_INDEX_ACCOUNT_NAME);
+ accountType = cursor.getString(
+ AccountsLoader.COLUMN_INDEX_ACCOUNT_TYPE);
+ rootFolderId = cursor.getLong(
+ AccountsLoader.COLUMN_INDEX_ROOT_ID);
+ mLabel = accountName;
+ if (TextUtils.isEmpty(mLabel)) {
+ mLabel = context.getString(R.string.local_bookmarks);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return mLabel;
+ }
+ }
+
+ static class EditBookmarkInfo {
+ long id = -1;
+ long parentId = -1;
+ String parentTitle;
+ String title;
+ String accountName;
+ String accountType;
+
+ long lastUsedId = -1;
+ String lastUsedTitle;
+ String lastUsedAccountName;
+ String lastUsedAccountType;
+ }
+
+ static class EditBookmarkInfoLoader extends AsyncTaskLoader<EditBookmarkInfo> {
+
+ private Context mContext;
+ private Bundle mMap;
+
+ public EditBookmarkInfoLoader(Context context, Bundle bundle) {
+ super(context);
+ mContext = context;
+ mMap = bundle;
+ }
+
+ @Override
+ public EditBookmarkInfo loadInBackground() {
+ final ContentResolver cr = mContext.getContentResolver();
+ EditBookmarkInfo info = new EditBookmarkInfo();
+ Cursor c = null;
+
+ try {
+ // First, let's lookup the bookmark (check for dupes, get needed info)
+ String url = mMap.getString(BrowserContract.Bookmarks.URL);
+ info.id = mMap.getLong(BrowserContract.Bookmarks._ID, -1);
+ boolean checkForDupe = mMap.getBoolean(CHECK_FOR_DUPE);
+ if (checkForDupe && info.id == -1 && !TextUtils.isEmpty(url)) {
+ c = cr.query(BrowserContract.Bookmarks.CONTENT_URI,
+ new String[] { BrowserContract.Bookmarks._ID},
+ BrowserContract.Bookmarks.URL + "=?",
+ new String[] { url }, null);
+ if (c.getCount() == 1 && c.moveToFirst()) {
+ info.id = c.getLong(0);
+ }
+ c.close();
+ }
+ if (info.id != -1) {
+ c = cr.query(ContentUris.withAppendedId(
+ BrowserContract.Bookmarks.CONTENT_URI, info.id),
+ new String[] {
+ BrowserContract.Bookmarks.PARENT,
+ BrowserContract.Bookmarks.ACCOUNT_NAME,
+ BrowserContract.Bookmarks.ACCOUNT_TYPE,
+ BrowserContract.Bookmarks.TITLE},
+ null, null, null);
+ if (c.moveToFirst()) {
+ info.parentId = c.getLong(0);
+ info.accountName = c.getString(1);
+ info.accountType = c.getString(2);
+ info.title = c.getString(3);
+ }
+ c.close();
+ c = cr.query(ContentUris.withAppendedId(
+ BrowserContract.Bookmarks.CONTENT_URI, info.parentId),
+ new String[] {
+ BrowserContract.Bookmarks.TITLE,},
+ null, null, null);
+ if (c.moveToFirst()) {
+ info.parentTitle = c.getString(0);
+ }
+ c.close();
+ }
+
+ // Figure out the last used folder/account
+ c = cr.query(BrowserContract.Bookmarks.CONTENT_URI,
+ new String[] {
+ BrowserContract.Bookmarks.PARENT,
+ }, null, null,
+ BrowserContract.Bookmarks.DATE_MODIFIED + " DESC LIMIT 1");
+ if (c.moveToFirst()) {
+ long parent = c.getLong(0);
+ c.close();
+ c = cr.query(BrowserContract.Bookmarks.CONTENT_URI,
+ new String[] {
+ BrowserContract.Bookmarks.TITLE,
+ BrowserContract.Bookmarks.ACCOUNT_NAME,
+ BrowserContract.Bookmarks.ACCOUNT_TYPE},
+ BrowserContract.Bookmarks._ID + "=?", new String[] {
+ Long.toString(parent)}, null);
+ if (c.moveToFirst()) {
+ info.lastUsedId = parent;
+ info.lastUsedTitle = c.getString(0);
+ info.lastUsedAccountName = c.getString(1);
+ info.lastUsedAccountType = c.getString(2);
+ }
+ c.close();
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+
+ return info;
+ }
+
+ @Override
+ protected void onStartLoading() {
+ forceLoad();
+ }
+
+ }
+
}
diff --git a/src/com/android/browser/AutoFillSettingsFragment.java b/src/com/android/browser/AutoFillSettingsFragment.java
index 3a7ae12..e87645e 100644
--- a/src/com/android/browser/AutoFillSettingsFragment.java
+++ b/src/com/android/browser/AutoFillSettingsFragment.java
@@ -53,6 +53,7 @@
// Used to display toast after DB interactions complete.
private Handler mHandler;
+ private BrowserSettings mSettings;
private final static int PROFILE_SAVED_MSG = 100;
private final static int PROFILE_DELETED_MSG = 101;
@@ -130,6 +131,7 @@
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
+ mSettings = BrowserSettings.getInstance();
}
@Override
@@ -177,7 +179,7 @@
mCountryEdit.getText().toString(),
mPhoneEdit.getText().toString());
- BrowserSettings.getInstance().setAutoFillProfile(getActivity(), newProfile,
+ mSettings.setAutoFillProfile(newProfile,
mHandler.obtainMessage(PROFILE_SAVED_MSG));
closeEditor();
}
@@ -200,7 +202,7 @@
// Update browser settings and native with a null profile. This will
// trigger the current profile to get deleted from the DB.
- BrowserSettings.getInstance().setAutoFillProfile(getActivity(), null,
+ mSettings.setAutoFillProfile(null,
mHandler.obtainMessage(PROFILE_DELETED_MSG));
updateButtonState();
@@ -215,7 +217,7 @@
});
// Populate the text boxes with any pre existing AutoFill data.
- AutoFillProfile activeProfile = BrowserSettings.getInstance().getAutoFillProfile();
+ AutoFillProfile activeProfile = mSettings.getAutoFillProfile();
if (activeProfile != null) {
mFullNameEdit.setText(activeProfile.getFullName());
mEmailEdit.setText(activeProfile.getEmailAddress());
diff --git a/src/com/android/browser/AutofillHandler.java b/src/com/android/browser/AutofillHandler.java
new file mode 100644
index 0000000..b6b237d
--- /dev/null
+++ b/src/com/android/browser/AutofillHandler.java
@@ -0,0 +1,202 @@
+
+/*
+ * Copyright (C) 2011 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.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.webkit.WebSettings.AutoFillProfile;
+
+import java.util.concurrent.CountDownLatch;
+
+public class AutofillHandler {
+
+ private AutoFillProfile mAutoFillProfile;
+ // Default to zero. In the case no profile is set up, the initial
+ // value will come from the AutoFillSettingsFragment when the user
+ // creates a profile. Otherwise, we'll read the ID of the last used
+ // profile from the prefs db.
+ private int mAutoFillActiveProfileId;
+ private static final int NO_AUTOFILL_PROFILE_SET = 0;
+
+ private CountDownLatch mLoaded = new CountDownLatch(1);
+ private Context mContext;
+
+ public AutofillHandler(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Load settings from the browser app's database. It is performed in
+ * an AsyncTask as it involves plenty of slow disk IO.
+ * NOTE: Strings used for the preferences must match those specified
+ * in the various preference XML files.
+ */
+ public void asyncLoadFromDb() {
+ // Run the initial settings load in an AsyncTask as it hits the
+ // disk multiple times through SharedPreferences and SQLite. We
+ // need to be certain though that this has completed before we start
+ // to load pages though, so in the worst case we will block waiting
+ // for it to finish in BrowserActivity.onCreate().
+ new LoadFromDb().start();
+ }
+
+ public void waitForLoad() {
+ try {
+ mLoaded.await();
+ } catch (InterruptedException e) {}
+ }
+
+ private class LoadFromDb extends Thread {
+
+ @Override
+ public void run() {
+ SharedPreferences p =
+ PreferenceManager.getDefaultSharedPreferences(mContext);
+
+ // Read the last active AutoFill profile id.
+ mAutoFillActiveProfileId = p.getInt(
+ PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID,
+ mAutoFillActiveProfileId);
+
+ // Load the autofill profile data from the database. We use a database separate
+ // to the browser preference DB to make it easier to support multiple profiles
+ // and switching between them.
+ AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
+ Cursor c = autoFillDb.getProfile(mAutoFillActiveProfileId);
+
+ if (c.getCount() > 0) {
+ c.moveToFirst();
+
+ String fullName = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.FULL_NAME));
+ String email = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
+ String company = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.COMPANY_NAME));
+ String addressLine1 = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
+ String addressLine2 = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
+ String city = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.CITY));
+ String state = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.STATE));
+ String zip = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.ZIP_CODE));
+ String country = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.COUNTRY));
+ String phone = c.getString(c.getColumnIndex(
+ AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
+ mAutoFillProfile = new AutoFillProfile(mAutoFillActiveProfileId,
+ fullName, email, company, addressLine1, addressLine2, city,
+ state, zip, country, phone);
+ }
+ c.close();
+ autoFillDb.close();
+
+ mLoaded.countDown();
+ }
+ }
+
+ public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
+ int profileId = NO_AUTOFILL_PROFILE_SET;
+ if (profile != null) {
+ profileId = profile.getUniqueId();
+ // Update the AutoFill DB with the new profile.
+ new SaveProfileToDbTask(msg).execute(profile);
+ } else {
+ // Delete the current profile.
+ if (mAutoFillProfile != null) {
+ new DeleteProfileFromDbTask(msg).execute(mAutoFillProfile.getUniqueId());
+ }
+ }
+ // Make sure we set mAutoFillProfile before calling setActiveAutoFillProfileId
+ // Calling setActiveAutoFillProfileId will trigger an update of WebViews
+ // which will expect a new profile to be set
+ mAutoFillProfile = profile;
+ setActiveAutoFillProfileId(profileId);
+ }
+
+ public AutoFillProfile getAutoFillProfile() {
+ return mAutoFillProfile;
+ }
+
+ private void setActiveAutoFillProfileId(int activeProfileId) {
+ mAutoFillActiveProfileId = activeProfileId;
+ Editor ed = PreferenceManager.
+ getDefaultSharedPreferences(mContext).edit();
+ ed.putInt(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
+ ed.apply();
+ }
+
+ private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
+ AutoFillProfileDatabase mAutoFillProfileDb;
+ Message mCompleteMessage;
+
+ public AutoFillProfileDbTask(Message msg) {
+ mCompleteMessage = msg;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ if (mCompleteMessage != null) {
+ mCompleteMessage.sendToTarget();
+ }
+ mAutoFillProfileDb.close();
+ }
+
+ @Override
+ abstract protected Void doInBackground(T... values);
+ }
+
+
+ private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
+ public SaveProfileToDbTask(Message msg) {
+ super(msg);
+ }
+
+ @Override
+ protected Void doInBackground(AutoFillProfile... values) {
+ mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
+ assert mAutoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
+ AutoFillProfile newProfile = values[0];
+ mAutoFillProfileDb.addOrUpdateProfile(mAutoFillActiveProfileId, newProfile);
+ return null;
+ }
+ }
+
+ private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
+ public DeleteProfileFromDbTask(Message msg) {
+ super(msg);
+ }
+
+ @Override
+ protected Void doInBackground(Integer... values) {
+ mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
+ int id = values[0];
+ assert id > 0;
+ mAutoFillProfileDb.dropProfile(id);
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 4f80e9d..b20e661 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -17,14 +17,20 @@
package com.android.browser;
import com.android.browser.Tab.LockIcon;
+import com.android.internal.view.menu.MenuBuilder;
import android.animation.ObjectAnimator;
import android.app.Activity;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.PaintDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -72,13 +78,15 @@
private Drawable mSecLockIcon;
private Drawable mMixLockIcon;
+ protected Drawable mGenericFavicon;
private FrameLayout mBrowserFrameLayout;
protected FrameLayout mContentView;
- private FrameLayout mCustomViewContainer;
+ protected FrameLayout mCustomViewContainer;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
+ private int mOriginalOrientation;
private CombinedBookmarkHistoryView mComboView;
@@ -86,7 +94,6 @@
private Toast mStopToast;
- private boolean mTitleShowing;
// the default <video> poster
private Bitmap mDefaultVideoPoster;
@@ -116,7 +123,23 @@
mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
.findViewById(R.id.fullscreen_custom_content);
frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
- mTitleShowing = false;
+ setFullscreen(BrowserSettings.getInstance().useFullscreen());
+ mGenericFavicon = res.getDrawable(
+ R.drawable.app_web_browser_sm);
+ }
+
+ @Override
+ public WebView createWebView(boolean privateBrowsing) {
+ // Create a new WebView
+ BrowserWebView w = new BrowserWebView(mActivity, null,
+ android.R.attr.webViewStyle, privateBrowsing);
+ initWebViewSettings(w);
+ return w;
+ }
+
+ @Override
+ public WebView createSubWebView(boolean privateBrowsing) {
+ return createWebView(privateBrowsing);
}
/**
@@ -129,11 +152,15 @@
w.setMapTrackballToArrowKeys(false); // use trackball directly
// Enable the built-in zoom
w.getSettings().setBuiltInZoomControls(true);
+ boolean supportsMultiTouch = mActivity.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH);
+ w.getSettings().setDisplayZoomControls(!supportsMultiTouch);
+ w.setExpandedTileBounds(true); // smoother scrolling
// Add this WebView to the settings observer list and update the
// settings
final BrowserSettings s = BrowserSettings.getInstance();
- s.addObserver(w.getSettings()).update(s, null);
+ s.startManagingSettings(w.getSettings());
}
private void cancelStopToast() {
@@ -164,8 +191,6 @@
public void onConfigurationChanged(Configuration config) {
}
- public abstract void editUrl(boolean clearInput);
-
// key handling
@Override
@@ -183,6 +208,11 @@
return false;
}
+ @Override
+ public boolean onMenuKey() {
+ return false;
+ }
+
// Tab callbacks
@Override
public void onTabDataChanged(Tab tab) {
@@ -212,7 +242,7 @@
@Override
public boolean needsRestoreAllTabs() {
- return false;
+ return true;
}
@Override
@@ -300,8 +330,6 @@
Log.w(LOGTAG, "mContainer is already attached to content in"
+ " attachTabToContentView!");
}
- mainView.setNextFocusUpId(R.id.url_focused);
- mainView.setNextFocusDownId(R.id.url_focused);
mUiController.attachSubWindow(tab);
}
@@ -395,24 +423,43 @@
mContentView.addView(container, COVER_SCREEN_PARAMS);
}
+ protected void refreshWebView() {
+ WebView web = getWebView();
+ if (web != null) {
+ web.invalidate();
+ }
+ }
+
+ public void editUrl(boolean clearInput) {
+ if (mUiController.isInCustomActionMode()) {
+ mUiController.endActionMode();
+ }
+ showTitleBar();
+ getTitleBar().startEditingUrl(clearInput);
+ }
+
boolean canShowTitleBar() {
return !isTitleBarShowing()
&& !isActivityPaused()
&& (getActiveTab() != null)
- && (getActiveTab().getWebView() != null)
+ && (getWebView() != null)
&& !mUiController.isInCustomActionMode();
}
void showTitleBar() {
- mTitleShowing = true;
+ if (canShowTitleBar()) {
+ getTitleBar().show();
+ }
}
protected void hideTitleBar() {
- mTitleShowing = false;
+ if (getTitleBar().isShowing()) {
+ getTitleBar().hide();
+ }
}
protected boolean isTitleBarShowing() {
- return mTitleShowing;
+ return getTitleBar().isShowing();
}
protected abstract TitleBarBase getTitleBar();
@@ -421,24 +468,28 @@
WebView web = getWebView();
if (web != null) {
web.setTitleBarGravity(gravity);
- web.invalidate();
}
}
@Override
- public void showVoiceTitleBar(String title) {
- getTitleBar().setInVoiceMode(true);
+ public void showVoiceTitleBar(String title, List<String> results) {
+ getTitleBar().setInVoiceMode(true, results);
getTitleBar().setDisplayTitle(title);
}
@Override
public void revertVoiceTitleBar(Tab tab) {
- getTitleBar().setInVoiceMode(false);
+ getTitleBar().setInVoiceMode(false, null);
String url = tab.getUrl();
getTitleBar().setDisplayTitle(url);
}
@Override
+ public void registerDropdownChangeListener(DropdownChangeListener d) {
+ getTitleBar().registerDropdownChangeListener(d);
+ }
+
+ @Override
public void showComboView(boolean startWithHistory, Bundle extras) {
if (mComboView != null) {
return;
@@ -452,8 +503,9 @@
FrameLayout wrapper =
(FrameLayout) mContentView.findViewById(R.id.webview_wrapper);
wrapper.setVisibility(View.GONE);
- hideTitleBar();
+ getTitleBar().stopEditingUrl();
dismissIME();
+ hideTitleBar();
if (mActiveTab != null) {
WebView web = mActiveTab.getWebView();
mActiveTab.putInBackground();
@@ -489,7 +541,7 @@
}
@Override
- public void showCustomView(View view,
+ public void showCustomView(View view, int requestedOrientation,
WebChromeClient.CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
@@ -497,6 +549,8 @@
return;
}
+ mOriginalOrientation = mActivity.getRequestedOrientation();
+
// Add the custom view to its container.
mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
mCustomView = view;
@@ -505,6 +559,7 @@
mContentView.setVisibility(View.GONE);
// Finally show the custom view container.
setStatusBarVisibility(false);
+ mActivity.setRequestedOrientation(requestedOrientation);
mCustomViewContainer.setVisibility(View.VISIBLE);
mCustomViewContainer.bringToFront();
}
@@ -522,6 +577,7 @@
mCustomViewContainer.setVisibility(View.GONE);
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
+ mActivity.setRequestedOrientation(mOriginalOrientation);
setStatusBarVisibility(true);
mContentView.setVisibility(View.VISIBLE);
}
@@ -559,7 +615,9 @@
protected void updateNavigationState(Tab tab) {
}
- protected void updateAutoLogin(Tab tab, boolean animate) {}
+ protected void updateAutoLogin(Tab tab, boolean animate) {
+ getTitleBar().updateAutoLogin(tab, animate);
+ }
/**
* Update the lock icon to correspond to our latest state.
@@ -605,11 +663,6 @@
@Override
public void onActionModeFinished(boolean inLoad) {
- if (inLoad) {
- // the titlebar was removed when the CAB was shown
- // if the page is loading, show it again
- showTitleBar();
- }
}
// active tabs page
@@ -718,16 +771,59 @@
warning.show();
}
- @Override
- public void registerDropdownChangeListener(DropdownChangeListener d) {
+ protected void captureTab(final Tab tab) {
+ captureTab(tab,
+ (int) mActivity.getResources()
+ .getDimension(R.dimen.qc_thumb_width),
+ (int) mActivity.getResources()
+ .getDimension(R.dimen.qc_thumb_height));
+ }
+
+ protected void captureTab(final Tab tab, int width, int height) {
+ if ((tab == null) || (tab.getWebView() == null)) return;
+ Bitmap sshot = Controller.createScreenshot(tab, width, height);
+ tab.setScreenshot(sshot);
}
protected WebView getWebView() {
- Tab tab = getActiveTab();
- if (tab != null) {
- return tab.getWebView();
+ if (mActiveTab != null) {
+ return mActiveTab.getWebView();
+ } else {
+ return null;
}
- return null;
+ }
+
+ protected Menu getMenu() {
+ MenuBuilder menu = new MenuBuilder(mActivity);
+ mActivity.getMenuInflater().inflate(R.menu.browser, menu);
+ return menu;
+ }
+
+ public void setFullscreen(boolean enabled) {
+ if (enabled) {
+ mActivity.getWindow().setFlags(
+ WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ } else {
+ mActivity.getWindow().clearFlags(
+ WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ }
+ }
+
+ protected Drawable getFaviconDrawable(Bitmap icon) {
+ Drawable[] array = new Drawable[3];
+ array[0] = new PaintDrawable(Color.BLACK);
+ PaintDrawable p = new PaintDrawable(Color.WHITE);
+ array[1] = p;
+ if (icon == null) {
+ array[2] = mGenericFavicon;
+ } else {
+ array[2] = new BitmapDrawable(icon);
+ }
+ LayerDrawable d = new LayerDrawable(array);
+ d.setLayerInset(1, 1, 1, 1, 1);
+ d.setLayerInset(2, 2, 2, 2, 2);
+ return d;
}
}
diff --git a/src/com/android/browser/BookmarkDragHandler.java b/src/com/android/browser/BookmarkDragHandler.java
new file mode 100644
index 0000000..fc0752f
--- /dev/null
+++ b/src/com/android/browser/BookmarkDragHandler.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 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.ClipData;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BrowserContract;
+import android.view.ActionMode;
+import android.view.ActionMode.Callback;
+import android.view.DragEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnDragListener;
+import android.view.ViewGroup;
+
+public class BookmarkDragHandler implements Callback {
+
+ public static interface BookmarkDragController {
+ boolean startDrag(Cursor item);
+
+ ViewGroup getActionModeView(ActionMode mode, BookmarkDragState state);
+ void actionItemClicked(View v, BookmarkDragState state);
+ }
+
+ public static interface BookmarkDragAdapter {
+ void setBookmarkDragHandler(BookmarkDragHandler handler);
+ Cursor getItemForView(View v);
+ }
+
+ public static class BookmarkDragState {
+ public long id;
+ public long parent;
+ public Object extraState;
+ }
+
+ static final String BOOKMARK_DRAG_LABEL = "com.android.browser.BOOKMARK_LABEL";
+
+ private Activity mActivity;
+ private BookmarkDragController mDragController;
+ private BookmarkDragAdapter mDragAdapter;
+ private ActionMode mActionMode;
+ private BookmarkDragState mDragState;
+
+ public BookmarkDragHandler(Activity activity, BookmarkDragController controller,
+ BookmarkDragAdapter adapter) {
+ mActivity = activity;
+ mDragController = controller;
+ mDragAdapter = adapter;
+ mDragAdapter.setBookmarkDragHandler(this);
+ }
+
+ public boolean startDrag(View view, Cursor item, long id, Object extraState) {
+ if (!mDragController.startDrag(item)) {
+ return false;
+ }
+ Uri uri = ContentUris.withAppendedId(
+ BrowserContract.Bookmarks.CONTENT_URI, id);
+ ClipData data = ClipData.newRawUri(BOOKMARK_DRAG_LABEL, uri);
+ BookmarkDragState state = new BookmarkDragState();
+ state.id = id;
+ state.parent = item.getLong(BookmarksLoader.COLUMN_INDEX_PARENT);
+ state.extraState = extraState;
+ mDragState = state;
+ view.startDrag(data, new View.DragShadowBuilder(view), state, 0);
+ mActionMode = view.startActionMode(this);
+ return true;
+ }
+
+ public void registerBookmarkDragHandler(View view) {
+ view.setOnDragListener(mBookmarkDragListener);
+ }
+
+ private OnDragListener mBookmarkDragListener = new OnDragListener() {
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ Cursor c = mDragAdapter.getItemForView(v);
+ BookmarkDragState state = (BookmarkDragState) event.getLocalState();
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ return true;
+ case DragEvent.ACTION_DROP:
+ long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
+ if (id == state.id) {
+ // We dropped onto ourselves, show the context menu
+ v.showContextMenu();
+ return false;
+ }
+ long parent = c.getLong(BookmarksLoader.COLUMN_INDEX_PARENT);
+ if (isFolder(c)) {
+ parent = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
+ }
+ if (parent != state.parent) {
+ ContentResolver cr = mActivity.getContentResolver();
+ ContentValues values = new ContentValues();
+ values.put(BrowserContract.Bookmarks.PARENT, parent);
+ Uri uri = event.getClipData().getItemAt(0).getUri();
+ cr.update(uri, values, null, null);
+ }
+ break;
+ }
+ return false;
+ }
+ };
+
+ private OnDragListener mActionModeDragListener = new OnDragListener() {
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ BookmarkDragState state = (BookmarkDragState) event.getLocalState();
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ return true;
+ case DragEvent.ACTION_DROP:
+ mDragController.actionItemClicked(v, state);
+ // fall through
+ case DragEvent.ACTION_DRAG_ENDED:
+ if (mActionMode != null) {
+ mActionMode.finish();
+ mActionMode = null;
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ static boolean isFolder(Cursor c) {
+ return c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ ViewGroup view = mDragController.getActionModeView(mode, mDragState);
+ int count = view.getChildCount();
+ for (int i = 0; i < count; i++) {
+ view.getChildAt(i).setOnDragListener(mActionModeDragListener);
+ }
+ mode.setCustomView(view);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ }
+
+}
diff --git a/src/com/android/browser/BookmarkItem.java b/src/com/android/browser/BookmarkItem.java
index 4e60073..e7f37a5 100644
--- a/src/com/android/browser/BookmarkItem.java
+++ b/src/com/android/browser/BookmarkItem.java
@@ -30,6 +30,8 @@
*/
class BookmarkItem extends LinearLayout {
+ final static int MAX_TEXTVIEW_LEN = 80;
+
protected TextView mTextView;
protected TextView mUrlText;
protected ImageView mImageView;
@@ -63,6 +65,16 @@
item.mImageView.setImageDrawable(mImageView.getDrawable());
}
+ public void startMarquee() {
+ mTextView.setSelected(true);
+ mUrlText.setSelected(true);
+ }
+
+ public void stopMarquee() {
+ mTextView.setSelected(false);
+ mUrlText.setSelected(false);
+ }
+
/**
* Return the name assigned to this bookmark item.
*/
@@ -111,8 +123,8 @@
mTitle = name;
- if (name.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
- name = name.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+ if (name.length() > MAX_TEXTVIEW_LEN) {
+ name = name.substring(0, MAX_TEXTVIEW_LEN);
}
mTextView.setText(name);
@@ -129,8 +141,8 @@
mUrl = url;
- if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
- url = url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+ if (url.length() > MAX_TEXTVIEW_LEN) {
+ url = url.substring(0, MAX_TEXTVIEW_LEN);
}
mUrlText.setText(url);
diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java
index 3aaf5d4..491c16c 100644
--- a/src/com/android/browser/BookmarkUtils.java
+++ b/src/com/android/browser/BookmarkUtils.java
@@ -25,7 +25,6 @@
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -42,7 +41,6 @@
import android.preference.PreferenceManager;
import android.provider.Browser;
import android.provider.BrowserContract;
-import android.util.DisplayMetrics;
public class BookmarkUtils {
private final static String LOGTAG = "BookmarkUtils";
@@ -218,19 +216,7 @@
}
/* package */ static Uri getBookmarksUri(Context context) {
- return addAccountInfo(context,
- BrowserContract.Bookmarks.CONTENT_URI.buildUpon()).build();
- }
-
- public static Uri.Builder addAccountInfo(Context context, Uri.Builder ub) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- ub.appendQueryParameter(
- BrowserContract.Bookmarks.PARAM_ACCOUNT_NAME,accountName);
- ub.appendQueryParameter(
- BrowserContract.Bookmarks.PARAM_ACCOUNT_TYPE, accountType);
- return ub;
+ return BrowserContract.Bookmarks.CONTENT_URI;
}
/**
diff --git a/src/com/android/browser/Bookmarks.java b/src/com/android/browser/Bookmarks.java
index e7dc729..bd3b872 100644
--- a/src/com/android/browser/Bookmarks.java
+++ b/src/com/android/browser/Bookmarks.java
@@ -72,10 +72,6 @@
ContentValues values = new ContentValues();
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- values.put(BrowserContract.Bookmarks.ACCOUNT_TYPE, accountType);
- values.put(BrowserContract.Bookmarks.ACCOUNT_NAME, accountName);
values.put(BrowserContract.Bookmarks.TITLE, name);
values.put(BrowserContract.Bookmarks.URL, url);
values.put(BrowserContract.Bookmarks.IS_FOLDER, 0);
diff --git a/src/com/android/browser/BookmarksLoader.java b/src/com/android/browser/BookmarksLoader.java
index 7722392..bc06497 100644
--- a/src/com/android/browser/BookmarksLoader.java
+++ b/src/com/android/browser/BookmarksLoader.java
@@ -49,8 +49,8 @@
ChromeSyncColumns.SERVER_UNIQUE, // 9
};
- private String mAccountType;
- private String mAccountName;
+ String mAccountType;
+ String mAccountName;
public BookmarksLoader(Context context, String accountType, String accountName) {
super(context, addAccount(Bookmarks.CONTENT_URI_DEFAULT_FOLDER, accountType, accountName),
diff --git a/src/com/android/browser/BreadCrumbView.java b/src/com/android/browser/BreadCrumbView.java
index 9aaecd7..6706deb 100644
--- a/src/com/android/browser/BreadCrumbView.java
+++ b/src/com/android/browser/BreadCrumbView.java
@@ -41,8 +41,8 @@
public class BreadCrumbView extends LinearLayout implements OnClickListener {
private static final int DIVIDER_PADDING = 12; // dips
- interface Controller {
- public void onTop(int level, Object data);
+ public interface Controller {
+ public void onTop(BreadCrumbView view, int level, Object data);
}
private ImageButton mBackButton;
@@ -52,6 +52,7 @@
private Drawable mSeparatorDrawable;
private float mDividerPadding;
private int mMaxVisible = -1;
+ private Context mContext;
/**
* @param context
@@ -81,12 +82,14 @@
}
private void init(Context ctx) {
+ mContext = ctx;
+ setFocusable(true);
mUseBackButton = false;
mCrumbs = new ArrayList<Crumb>();
- TypedArray a = ctx.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
+ TypedArray a = mContext.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
mSeparatorDrawable = a.getDrawable(com.android.internal.R.styleable.Theme_dividerVertical);
a.recycle();
- mDividerPadding = DIVIDER_PADDING * ctx.getResources().getDisplayMetrics().density;
+ mDividerPadding = DIVIDER_PADDING * mContext.getResources().getDisplayMetrics().density;
addBackButton();
}
@@ -134,9 +137,9 @@
public void notifyController() {
if (mController != null) {
if (mCrumbs.size() > 0) {
- mController.onTop(mCrumbs.size(), getTopCrumb().data);
+ mController.onTop(this, mCrumbs.size(), getTopCrumb().data);
} else {
- mController.onTop(0, null);
+ mController.onTop(this, 0, null);
}
}
}
diff --git a/src/com/android/browser/Browser.java b/src/com/android/browser/Browser.java
index f49da5d..65eb0ce 100644
--- a/src/com/android/browser/Browser.java
+++ b/src/com/android/browser/Browser.java
@@ -16,12 +16,9 @@
package com.android.browser;
-import android.os.FileUtils;
-import android.util.Log;
-
import android.app.Application;
import android.content.Intent;
-import android.webkit.CookieManager;
+import android.util.Log;
import android.webkit.CookieSyncManager;
import dalvik.system.VMRuntime;
@@ -52,9 +49,6 @@
public void onCreate() {
super.onCreate();
- // Set the umask so that native code creates files with the correct
- // permissions (0660)
- FileUtils.setUMask(FileUtils.S_IRWXO);
if (LOGV_ENABLED)
Log.v(LOGTAG, "Browser.onCreate: this=" + this);
@@ -63,7 +57,7 @@
TARGET_HEAP_UTILIZATION);
// create CookieSyncManager with current Context
CookieSyncManager.createInstance(this);
- BrowserSettings.getInstance().asyncLoadFromDb(this);
+ BrowserSettings.initialize(getApplicationContext());
}
static Intent createBrowserViewIntent() {
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index a9b65fd..dbcae2e 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -62,11 +62,6 @@
BrowserSettings settings = BrowserSettings.getInstance();
- // We load the first set of BrowserSettings from the db asynchronously
- // but if it has not completed at this point, we have no choice but
- // to block waiting for them to finish loading. :(
- settings.waitForLoadFromDbToComplete();
-
// render the browser in OpenGL
if (settings.isHardwareAccelerated()) {
// Set the flag in the activity's window
@@ -77,12 +72,6 @@
this.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
- // enable this to test the browser in 32bit
- if (false) {
- getWindow().setFormat(PixelFormat.RGBX_8888);
- BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
- }
-
// If this was a web search request, pass it on to the default web
// search provider and finish this activity.
if (IntentHandler.handleWebSearchIntent(this, null, getIntent())) {
@@ -126,7 +115,7 @@
protected void onNewIntent(Intent intent) {
if (ACTION_RESTART.equals(intent.getAction())) {
Bundle outState = new Bundle();
- mController.onSaveInstanceState(outState);
+ mController.onSaveInstanceState(outState, true);
finish();
getApplicationContext().startActivity(
new Intent(getApplicationContext(), BrowserActivity.class)
@@ -177,7 +166,7 @@
if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
}
- mController.onSaveInstanceState(outState);
+ mController.onSaveInstanceState(outState, true);
}
@Override
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
index 9e71077..7543528 100644
--- a/src/com/android/browser/BrowserBookmarksAdapter.java
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -20,7 +20,6 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -28,10 +27,9 @@
import android.widget.ImageView;
import android.widget.TextView;
-class BrowserBookmarksAdapter extends CursorAdapter {
+public class BrowserBookmarksAdapter extends CursorAdapter {
LayoutInflater mInflater;
int mCurrentView;
- Drawable mFaviconBackground;
/**
* Create a new BrowserBookmarksAdapter.
@@ -42,8 +40,6 @@
super(context, null, 0);
mInflater = LayoutInflater.from(context);
selectView(defaultView);
- float density = context.getResources().getDisplayMetrics().density;
- mFaviconBackground = BookmarkUtils.createListFaviconBackground(context);
}
@Override
@@ -101,9 +97,7 @@
} else {
favicon.setImageBitmap(faviconBitmap);
}
- //favicon.setBackgroundResource(R.drawable.bookmark_list_favicon_bg);
- // TODO: Switch to above instead of below once b/3353813 is fixed
- favicon.setBackgroundDrawable(mFaviconBackground);
+ favicon.setBackgroundResource(R.drawable.bookmark_list_favicon_bg);
}
}
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index c6bc2bc..d4d1c0d 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -16,8 +16,6 @@
package com.android.browser;
-import com.android.browser.BreadCrumbView.Crumb;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -25,11 +23,11 @@
import android.content.ClipboardManager;
import android.content.ContentUris;
import android.content.Context;
+import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
@@ -40,7 +38,9 @@
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BrowserContract;
+import android.provider.BrowserContract.Accounts;
import android.provider.BrowserContract.ChromeSyncColumns;
+import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
@@ -50,38 +50,49 @@
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebIconDatabase.IconListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.OnChildClickListener;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast;
+import com.android.browser.BookmarkDragHandler.BookmarkDragController;
+import com.android.browser.BookmarkDragHandler.BookmarkDragState;
+import com.android.browser.view.BookmarkExpandableGridView;
+import com.android.browser.view.BookmarkExpandableGridView.BookmarkContextMenuInfo;
+
+import java.util.HashMap;
+
interface BookmarksPageCallbacks {
// Return true if handled
boolean onBookmarkSelected(Cursor c, boolean isFolder);
// Return true if handled
boolean onOpenInNewWindow(Cursor c);
- void onFolderChanged(int level, Uri uri);
}
/**
* View showing the user's bookmarks in the browser.
*/
public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
- LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
- BreadCrumbView.Controller, OnMenuItemClickListener, OnSharedPreferenceChangeListener {
+ LoaderManager.LoaderCallbacks<Cursor>, IconListener,
+ BreadCrumbView.Controller, OnMenuItemClickListener, OnChildClickListener {
+
+ public static class ExtraDragState {
+ public int childPosition;
+ public int groupPosition;
+ }
static final String LOGTAG = "browser";
- static final int LOADER_BOOKMARKS = 1;
+ static final int LOADER_ACCOUNTS = 1;
+ static final int LOADER_BOOKMARKS = 100;
static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
- static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
-
- public static final String PREF_ACCOUNT_TYPE = "acct_type";
- public static final String PREF_ACCOUNT_NAME = "acct_name";
+ static final String ACCOUNT_TYPE = "account_type";
+ static final String ACCOUNT_NAME = "account_name";
static final int VIEW_THUMBNAILS = 1;
static final int VIEW_LIST = 2;
@@ -89,77 +100,74 @@
BookmarksPageCallbacks mCallbacks;
View mRoot;
- GridView mGrid;
+ BookmarkExpandableGridView mGrid;
ListView mList;
- BrowserBookmarksAdapter mAdapter;
boolean mDisableNewWindow;
- boolean mCanceled = false;
boolean mEnableContextMenu = true;
- boolean mShowRootFolder = false;
View mEmptyView;
int mCurrentView;
View mHeader;
- ViewGroup mHeaderContainer;
- BreadCrumbView mCrumbs;
- int mCrumbVisibility = View.VISIBLE;
- int mCrumbMaxVisible = -1;
- boolean mCrumbBackButton = false;
+ HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
+ BookmarkDragHandler mDragHandler;
static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb,
Bundle args, ViewGroup headerContainer) {
BrowserBookmarksPage bbp = new BrowserBookmarksPage();
bbp.mCallbacks = cb;
- bbp.mHeaderContainer = headerContainer;
bbp.setArguments(args);
return bbp;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- switch (id) {
- case LOADER_BOOKMARKS: {
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- String accountType = prefs.getString(PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(PREF_ACCOUNT_NAME, null);
- BookmarksLoader bl = new BookmarksLoader(getActivity(),
- accountType, accountName);
- if (mCrumbs != null) {
- Uri uri = (Uri) mCrumbs.getTopData();
- if (uri != null) {
- bl.setUri(uri);
- }
- }
- return bl;
- }
+ if (id == LOADER_ACCOUNTS) {
+ return new AccountsLoader(getActivity());
+ } else if (id >= LOADER_BOOKMARKS) {
+ String accountType = args.getString(ACCOUNT_TYPE);
+ String accountName = args.getString(ACCOUNT_NAME);
+ BookmarksLoader bl = new BookmarksLoader(getActivity(),
+ accountType, accountName);
+ return bl;
+ } else {
+ throw new UnsupportedOperationException("Unknown loader id " + id);
}
- throw new UnsupportedOperationException("Unknown loader id " + id);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
- switch (loader.getId()) {
- case LOADER_BOOKMARKS: {
- // Set the visibility of the empty vs. content views
- if (cursor == null || cursor.getCount() == 0) {
- mEmptyView.setVisibility(View.VISIBLE);
- mGrid.setVisibility(View.GONE);
- mList.setVisibility(View.GONE);
- } else {
- mEmptyView.setVisibility(View.GONE);
- setupBookmarkView();
- }
-
- // Give the new data to the adapter
- mAdapter.changeCursor(cursor);
- break;
+ if (loader.getId() == LOADER_ACCOUNTS) {
+ LoaderManager lm = getLoaderManager();
+ int id = LOADER_BOOKMARKS;
+ while (cursor.moveToNext()) {
+ String accountName = cursor.getString(0);
+ String accountType = cursor.getString(1);
+ Bundle args = new Bundle();
+ args.putString(ACCOUNT_NAME, accountName);
+ args.putString(ACCOUNT_TYPE, accountType);
+ BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
+ getActivity(), mCurrentView);
+ mBookmarkAdapters.put(id, adapter);
+ mGrid.addAccount(accountName, adapter);
+ lm.restartLoader(id, args, this);
+ id++;
}
+ // TODO: Figure out what a reload of these means
+ // Currently, a reload is triggered whenever bookmarks change
+ // This is less than ideal
+ // It also causes UI flickering as a new adapter is created
+ // instead of re-using an existing one when the account_name is the
+ // same.
+ // For now, this is a one-shot load
+ getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
+ } else if (loader.getId() >= LOADER_BOOKMARKS) {
+ BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
+ adapter.changeCursor(cursor);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
- onLoadFinished(loader, null);
+ // TODO: Figure out what to do here (if anything?)
}
long getFolderId() {
@@ -180,38 +188,42 @@
@Override
public boolean onContextItemSelected(MenuItem item) {
- final Activity activity = getActivity();
- // It is possible that the view has been canceled when we get to
- // this point as back has a higher priority
- if (mCanceled) {
- return false;
- }
- AdapterView.AdapterContextMenuInfo i =
- (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
+ BookmarkContextMenuInfo i = (BookmarkContextMenuInfo)item.getMenuInfo();
// If we have no menu info, we can't tell which item was selected.
if (i == null) {
return false;
}
- switch (item.getItemId()) {
+ if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) {
+ return true;
+ }
+ return super.onContextItemSelected(item);
+ }
+
+ public boolean handleContextItem(int itemId, int groupPosition,
+ int childPosition) {
+ final Activity activity = getActivity();
+ BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
+
+ switch (itemId) {
case R.id.open_context_menu_id:
- loadUrl(i.position);
+ loadUrl(adapter, childPosition);
break;
case R.id.edit_context_menu_id:
- editBookmark(i.position);
+ editBookmark(adapter, childPosition);
break;
case R.id.shortcut_context_menu_id:
- Cursor c = mAdapter.getItem(i.position);
+ Cursor c = adapter.getItem(childPosition);
activity.sendBroadcast(createShortcutIntent(getActivity(), c));
break;
case R.id.delete_context_menu_id:
- displayRemoveBookmarkDialog(i.position);
+ displayRemoveBookmarkDialog(adapter, childPosition);
break;
case R.id.new_window_context_menu_id:
- openInNewWindow(i.position);
+ openInNewWindow(adapter, childPosition);
break;
case R.id.share_link_context_menu_id: {
- Cursor cursor = mAdapter.getItem(i.position);
+ Cursor cursor = adapter.getItem(childPosition);
Controller.sharePage(activity,
cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
@@ -220,16 +232,16 @@
break;
}
case R.id.copy_url_context_menu_id:
- copy(getUrl(i.position));
+ copy(getUrl(adapter, childPosition));
break;
case R.id.homepage_context_menu_id: {
- BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position));
+ BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition));
Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
break;
}
// Only for the Most visited page
case R.id.save_to_bookmarks_menu_id: {
- Cursor cursor = mAdapter.getItem(i.position);
+ Cursor cursor = adapter.getItem(childPosition);
String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
// If the site is bookmarked, the item becomes remove from
@@ -238,7 +250,7 @@
break;
}
default:
- return super.onContextItemSelected(item);
+ return false;
}
return true;
}
@@ -270,8 +282,9 @@
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- Cursor cursor = mAdapter.getItem(info.position);
+ BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
+ BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
+ Cursor cursor = adapter.getItem(info.childPosition);
if (!canEdit(cursor)) {
return;
}
@@ -330,55 +343,37 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
-
- setHasOptionsMenu(true);
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ mCurrentView = prefs.getInt(PREF_SELECTED_VIEW, getDefaultView());
+ // TODO: Support list view
+ mCurrentView = VIEW_THUMBNAILS;
Bundle args = getArguments();
mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
+
+ setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- Context context = getActivity();
-
mRoot = inflater.inflate(R.layout.bookmarks, container, false);
mEmptyView = mRoot.findViewById(android.R.id.empty);
- mGrid = (GridView) mRoot.findViewById(R.id.grid);
- mGrid.setOnItemClickListener(this);
- mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity()));
+ mGrid = (BookmarkExpandableGridView) mRoot.findViewById(R.id.grid);
+ mGrid.setOnChildClickListener(this);
+ mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
+ mGrid.setBreadcrumbController(this);
mList = (ListView) mRoot.findViewById(R.id.list);
- mList.setOnItemClickListener(this);
+ // TODO: mList.setOnItemClickListener(this);
setEnableContextMenu(mEnableContextMenu);
+ mDragHandler = new BookmarkDragHandler(getActivity(), mDragController,
+ mGrid.getDragAdapter());
- // Prep the header
- ViewGroup hc = mHeaderContainer;
- if (hc == null) {
- hc = (ViewGroup) mRoot.findViewById(R.id.header_container);
- hc.setVisibility(View.VISIBLE);
- }
- mHeader = inflater.inflate(R.layout.bookmarks_header, hc, false);
- hc.addView(mHeader);
- mCrumbs = (BreadCrumbView) mHeader.findViewById(R.id.crumbs);
- mCrumbs.setController(this);
- mCrumbs.setUseBackButton(mCrumbBackButton);
- mCrumbs.setMaxVisible(mCrumbMaxVisible);
- mCrumbs.setVisibility(mCrumbVisibility);
- String name = getString(R.string.bookmarks);
- mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
- if (mCallbacks != null) {
- mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
- }
// Start the loaders
LoaderManager lm = getLoaderManager();
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- prefs.registerOnSharedPreferenceChangeListener(this);
- mCurrentView =
- prefs.getInt(PREF_SELECTED_VIEW, getDefaultView());
- mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView);
- lm.restartLoader(LOADER_BOOKMARKS, null, this);
+ lm.restartLoader(LOADER_ACCOUNTS, null, this);
// Add our own listener in case there are favicons that have yet to be loaded.
CombinedBookmarkHistoryView.getIconListenerSet().addListener(this);
@@ -396,16 +391,14 @@
@Override
public void onDestroyView() {
super.onDestroyView();
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- prefs.unregisterOnSharedPreferenceChangeListener(this);
- if (mHeaderContainer != null) {
- mHeaderContainer.removeView(mHeader);
+ mGrid.setBreadcrumbController(null);
+ LoaderManager lm = getLoaderManager();
+ lm.destroyLoader(LOADER_ACCOUNTS);
+ for (int id : mBookmarkAdapters.keySet()) {
+ lm.destroyLoader(id);
}
- mCrumbs.setController(null);
- mCrumbs = null;
- getLoaderManager().destroyLoader(LOADER_BOOKMARKS);
- mAdapter = null;
+ mBookmarkAdapters.clear();
+
CombinedBookmarkHistoryView.getIconListenerSet().removeListener(this);
}
@@ -413,35 +406,52 @@
public void onReceivedIcon(String url, Bitmap icon) {
// A new favicon has been loaded, so let anything attached to the adapter know about it
// so new icons will be loaded.
- mAdapter.notifyDataSetChanged();
+ // TODO: Notify all of data set changed
+ // TODO: Wait, is this even needed? Won't this trigger a DB change anyway?
+ }
+
+ private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
+ if (mCurrentView == VIEW_THUMBNAILS) {
+ return mGrid.getChildAdapter(groupPosition);
+ } else {
+ // TODO: Support expandable list
+ return null;
+ }
+ }
+
+ private BreadCrumbView getBreadCrumbs(int groupPosition) {
+ if (mCurrentView == VIEW_THUMBNAILS) {
+ return mGrid.getBreadCrumbs(groupPosition);
+ } else {
+ // TODO: Support expandable list
+ return null;
+ }
}
@Override
- public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- // It is possible that the view has been canceled when we get to
- // this point as back has a higher priority
- if (mCanceled) {
- android.util.Log.e(LOGTAG, "item clicked when dismissing");
- return;
- }
-
- Cursor cursor = mAdapter.getItem(position);
+ public boolean onChildClick(ExpandableListView parent, View v,
+ int groupPosition, int childPosition, long id) {
+ BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
+ Cursor cursor = adapter.getItem(childPosition);
boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
if (mCallbacks != null &&
mCallbacks.onBookmarkSelected(cursor, isFolder)) {
- return;
+ return true;
}
+ // TODO: Folder stuff
if (isFolder) {
String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Uri uri = ContentUris.withAppendedId(
BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
- if (mCrumbs != null) {
+ BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
+ if (crumbs != null) {
// update crumbs
- mCrumbs.pushView(title, uri);
+ crumbs.pushView(title, uri);
}
- loadFolder(uri);
+ loadFolder(groupPosition, uri);
}
+ return true;
}
/* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
@@ -452,15 +462,15 @@
return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
}
- private void loadUrl(int position) {
- if (mCallbacks != null && mAdapter != null) {
- mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false);
+ private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
+ if (mCallbacks != null && adapter != null) {
+ mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
}
}
- private void openInNewWindow(int position) {
+ private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
if (mCallbacks != null) {
- Cursor c = mAdapter.getItem(position);
+ Cursor c = adapter.getItem(position);
boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
if (isFolder) {
long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
@@ -497,9 +507,9 @@
}
- private void editBookmark(int position) {
+ private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
- Cursor cursor = mAdapter.getItem(position);
+ Cursor cursor = adapter.getItem(position);
Bundle item = new Bundle();
item.putString(BrowserContract.Bookmarks.TITLE,
cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
@@ -520,18 +530,19 @@
startActivity(intent);
}
- private void displayRemoveBookmarkDialog(final int position) {
+ private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
+ int position) {
// Put up a dialog asking if the user really wants to
// delete the bookmark
- Cursor cursor = mAdapter.getItem(position);
+ Cursor cursor = adapter.getItem(position);
long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Context context = getActivity();
BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
}
- private String getUrl(int position) {
- return getUrl(mAdapter.getItem(position));
+ private String getUrl(BrowserBookmarksAdapter adapter, int position) {
+ return getUrl(adapter.getItem(position));
}
/* package */ static String getUrl(Cursor c) {
@@ -563,6 +574,7 @@
Resources res = getActivity().getResources();
int horizontalSpacing = (int) res.getDimension(R.dimen.combo_horizontalSpacing);
mGrid.setHorizontalSpacing(horizontalSpacing);
+ mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
int paddingLeftRight = (int) res.getDimension(R.dimen.combo_paddingLeftRight);
int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
mRoot.setPadding(paddingLeftRight, paddingTop,
@@ -578,10 +590,11 @@
}
void selectView(int view) {
+ // TODO: Support list view
+ view = mCurrentView;
if (view == mCurrentView) {
return;
}
- mCurrentView = view;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
Editor edit = prefs.edit();
edit.putInt(PREF_SELECTED_VIEW, mCurrentView);
@@ -593,52 +606,53 @@
}
private void setupBookmarkView() {
- mAdapter.selectView(mCurrentView);
- switch (mCurrentView) {
- case VIEW_THUMBNAILS:
- mList.setAdapter(null);
- if (mGrid.getAdapter() != mAdapter) {
- mGrid.setAdapter(mAdapter);
- }
- mGrid.setVisibility(View.VISIBLE);
- mList.setVisibility(View.GONE);
- break;
- case VIEW_LIST:
- mGrid.setAdapter(null);
- if (mList.getAdapter() != mAdapter) {
- mList.setAdapter(mAdapter);
- }
- mGrid.setVisibility(View.GONE);
- mList.setVisibility(View.VISIBLE);
- break;
- }
+ // TODO: Support list view
+// mAdapter.selectView(mCurrentView);
+// switch (mCurrentView) {
+// case VIEW_THUMBNAILS:
+// mList.setAdapter(null);
+// SharedPreferences prefs = PreferenceManager
+// .getDefaultSharedPreferences(getActivity());
+// String accountName = prefs.getString(PREF_ACCOUNT_NAME, null);
+// mGrid.addAccount(accountName, mAdapter);
+// mGrid.setVisibility(View.VISIBLE);
+// mList.setVisibility(View.GONE);
+// break;
+// case VIEW_LIST:
+// mGrid.clearAccounts();
+// if (mList.getAdapter() != mAdapter) {
+// mList.setAdapter(mAdapter);
+// }
+// mGrid.setVisibility(View.GONE);
+// mList.setVisibility(View.VISIBLE);
+// break;
+// }
}
/**
* BreadCrumb controller callback
*/
@Override
- public void onTop(int level, Object data) {
+ public void onTop(BreadCrumbView view, int level, Object data) {
+ int groupPosition = (Integer) view.getTag(R.id.group_position);
Uri uri = (Uri) data;
if (uri == null) {
// top level
uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
}
- loadFolder(uri);
+ loadFolder(groupPosition, uri);
}
/**
* @param uri
*/
- private void loadFolder(Uri uri) {
+ private void loadFolder(int groupPosition, Uri uri) {
LoaderManager manager = getLoaderManager();
- BookmarksLoader loader =
- (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
+ // This assumes groups are ordered the same as loaders
+ BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
+ manager.getLoader(LOADER_BOOKMARKS + groupPosition));
loader.setUri(uri);
loader.forceLoad();
- if (mCallbacks != null) {
- mCallbacks.onFolderChanged(mCrumbs.getTopLevel(), uri);
- }
}
@Override
@@ -655,18 +669,9 @@
}
public boolean onBackPressed() {
- if (canGoBack()) {
- mCrumbs.popView();
- return true;
- }
return false;
}
- private boolean canGoBack() {
- Crumb c = mCrumbs.getTopCrumb();
- return c != null && c.canGoBack;
- }
-
public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
mCallbacks = callbackListener;
}
@@ -691,6 +696,49 @@
}
}
+ private BookmarkDragController mDragController = new BookmarkDragController() {
+
+ @Override
+ public boolean startDrag(Cursor item) {
+ return canEdit(item);
+ }
+
+ @Override
+ public ViewGroup getActionModeView(ActionMode mode,
+ BookmarkDragState state) {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ LinearLayout view = (LinearLayout) inflater.inflate(
+ R.layout.bookmarks_drag_actionmode, null);
+ view.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
+ ExtraDragState extraState = (ExtraDragState) state.extraState;
+ BrowserBookmarksAdapter adapter = getChildAdapter(extraState.groupPosition);
+ Cursor c = adapter.getItem(extraState.childPosition);
+ boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+ if (isFolder) {
+ view.findViewById(R.id.open_context_menu_id).setVisibility(View.GONE);
+ ImageView iv = (ImageView) view.findViewById(
+ R.id.new_window_context_menu_id);
+ iv.setImageResource(R.drawable.ic_windows_holo_dark);
+ }
+ return view;
+ }
+
+ @Override
+ public void actionItemClicked(View v, BookmarkDragState state) {
+ if (v.getId() == R.id.info) {
+ if (mCurrentView == VIEW_THUMBNAILS) {
+ mGrid.showContextMenuForState(state);
+ } else {
+ // TODO: Support expandable list
+ }
+ } else {
+ ExtraDragState extraState = (ExtraDragState) state.extraState;
+ handleContextItem(v.getId(), extraState.groupPosition,
+ extraState.childPosition);
+ }
+ }
+ };
+
private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> {
Context mContext;
BookmarkItem mHeader;
@@ -723,41 +771,17 @@
}
}
- public void setBreadCrumbVisibility(int visibility) {
- mCrumbVisibility = visibility;
- if (mCrumbs != null) {
- mCrumbs.setVisibility(mCrumbVisibility);
- }
- }
+ static class AccountsLoader extends CursorLoader {
- public void setBreadCrumbUseBackButton(boolean use) {
- mCrumbBackButton = use;
- if (mCrumbs != null) {
- mCrumbs.setUseBackButton(mCrumbBackButton);
- }
- }
+ static String[] ACCOUNTS_PROJECTION = new String[] {
+ Accounts.ACCOUNT_NAME,
+ Accounts.ACCOUNT_TYPE
+ };
- public void setBreadCrumbMaxVisible(int max) {
- mCrumbMaxVisible = max;
- if (mCrumbs != null) {
- mCrumbs.setMaxVisible(mCrumbMaxVisible);
+ public AccountsLoader(Context context) {
+ super(context, Accounts.CONTENT_URI, ACCOUNTS_PROJECTION, null, null,
+ Accounts.ACCOUNT_NAME + " ASC");
}
- }
- @Override
- public void onSharedPreferenceChanged(
- SharedPreferences sharedPreferences, String key) {
- if (PREF_ACCOUNT_NAME.equals(key) || PREF_ACCOUNT_TYPE.equals(key)) {
- mCrumbs.setController(null);
- mCrumbs.clear();
- LoaderManager lm = getLoaderManager();
- lm.restartLoader(LOADER_BOOKMARKS, null, this);
- mCrumbs.setController(this);
- String name = getString(R.string.bookmarks);
- mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
- if (mCallbacks != null) {
- mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
- }
- }
}
}
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 98be86d..bcc33e2 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -59,6 +59,9 @@
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
+import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@@ -68,7 +71,7 @@
* days of viewing.
*/
public class BrowserHistoryPage extends Fragment
- implements LoaderCallbacks<Cursor> {
+ implements LoaderCallbacks<Cursor>, OnChildClickListener {
static final int LOADER_HISTORY = 1;
static final int LOADER_MOST_VISITED = 2;
@@ -82,6 +85,7 @@
ListView mGroupList, mChildList;
private ViewGroup mPrefsContainer;
private FragmentBreadCrumbs mFragmentBreadCrumbs;
+ private ExpandableListView mHistoryList;
// Implementation of WebIconDatabase.IconListener
class IconReceiver implements IconListener {
@@ -132,11 +136,7 @@
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
getActivity());
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
Uri.Builder combinedBuilder = Combined.CONTENT_URI.buildUpon();
- combinedBuilder.appendQueryParameter(BrowserContract.Bookmarks.PARAM_ACCOUNT_TYPE, accountType);
- combinedBuilder.appendQueryParameter(BrowserContract.Bookmarks.PARAM_ACCOUNT_NAME, accountName);
switch (id) {
case LOADER_HISTORY: {
@@ -187,7 +187,7 @@
switch (loader.getId()) {
case LOADER_HISTORY: {
mAdapter.changeCursor(data);
- if (!mAdapter.isEmpty()
+ if (!mAdapter.isEmpty() && mGroupList != null
&& mGroupList.getCheckedItemPosition() == ListView.INVALID_POSITION) {
selectGroup(0);
}
@@ -229,7 +229,31 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.history, container, false);
+ mAdapter = new HistoryAdapter(getActivity());
ViewStub stub = (ViewStub) mRoot.findViewById(R.id.pref_stub);
+ if (stub != null) {
+ inflateTwoPane(stub);
+ } else {
+ inflateSinglePane();
+ }
+
+ // Start the loaders
+ getLoaderManager().restartLoader(LOADER_HISTORY, null, this);
+ getLoaderManager().restartLoader(LOADER_MOST_VISITED, null, this);
+
+ // Register to receive icons in case they haven't all been loaded.
+ CombinedBookmarkHistoryView.getIconListenerSet().addListener(mIconReceiver);
+ return mRoot;
+ }
+
+ private void inflateSinglePane() {
+ mHistoryList = (ExpandableListView) mRoot.findViewById(R.id.history);
+ mHistoryList.setAdapter(mAdapter);
+ mHistoryList.setOnChildClickListener(this);
+ registerForContextMenu(mHistoryList);
+ }
+
+ private void inflateTwoPane(ViewStub stub) {
stub.setLayoutResource(R.layout.preference_list_content);
stub.inflate();
mGroupList = (ListView) mRoot.findViewById(android.R.id.list);
@@ -238,7 +262,6 @@
mFragmentBreadCrumbs.setMaxVisible(1);
mFragmentBreadCrumbs.setActivity(getActivity());
mPrefsContainer.setVisibility(View.VISIBLE);
- mAdapter = new HistoryAdapter(getActivity());
mGroupList.setAdapter(new HistoryGroupWrapper(mAdapter));
mGroupList.setOnItemClickListener(mGroupItemClickListener);
mGroupList.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
@@ -249,14 +272,6 @@
registerForContextMenu(mChildList);
ViewGroup prefs = (ViewGroup) mRoot.findViewById(R.id.prefs);
prefs.addView(mChildList);
-
- // Start the loaders
- getLoaderManager().restartLoader(LOADER_HISTORY, null, this);
- getLoaderManager().restartLoader(LOADER_MOST_VISITED, null, this);
-
- // Register to receive icons in case they haven't all been loaded.
- CombinedBookmarkHistoryView.getIconListenerSet().addListener(mIconReceiver);
- return mRoot;
}
private OnItemClickListener mGroupItemClickListener = new OnItemClickListener() {
@@ -279,6 +294,13 @@
};
@Override
+ public boolean onChildClick(ExpandableListView parent, View view,
+ int groupPosition, int childPosition, long id) {
+ mCallbacks.onUrlSelected(((HistoryItem) view).getUrl(), false);
+ return true;
+ }
+
+ @Override
public void onDestroy() {
super.onDestroy();
CombinedBookmarkHistoryView.getIconListenerSet().removeListener(mIconReceiver);
@@ -341,17 +363,30 @@
}
}
+ View getTargetView(ContextMenuInfo menuInfo) {
+ if (menuInfo instanceof AdapterContextMenuInfo) {
+ return ((AdapterContextMenuInfo) menuInfo).targetView;
+ }
+ if (menuInfo instanceof ExpandableListContextMenuInfo) {
+ return ((ExpandableListContextMenuInfo) menuInfo).targetView;
+ }
+ return null;
+ }
+
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- AdapterContextMenuInfo i = (AdapterContextMenuInfo) menuInfo;
+
+ View targetView = getTargetView(menuInfo);
+ if (!(targetView instanceof HistoryItem)) {
+ return;
+ }
+ HistoryItem historyItem = (HistoryItem) targetView;
// Inflate the menu
Activity parent = getActivity();
MenuInflater inflater = parent.getMenuInflater();
inflater.inflate(R.menu.historycontext, menu);
- HistoryItem historyItem = (HistoryItem) i.targetView;
-
// Setup the header
if (mContextHeader == null) {
mContextHeader = new HistoryItem(parent, false);
@@ -382,12 +417,11 @@
@Override
public boolean onContextItemSelected(MenuItem item) {
- AdapterContextMenuInfo i =
- (AdapterContextMenuInfo) item.getMenuInfo();
- if (i == null) {
+ ContextMenuInfo menuInfo = item.getMenuInfo();
+ if (menuInfo == null) {
return false;
}
- HistoryItem historyItem = (HistoryItem) i.targetView;
+ HistoryItem historyItem = (HistoryItem) getTargetView(menuInfo);
String url = historyItem.getUrl();
String title = historyItem.getName();
Activity activity = getActivity();
@@ -417,7 +451,7 @@
Browser.deleteFromHistory(activity.getContentResolver(), url);
return true;
case R.id.homepage_context_menu_id:
- BrowserSettings.getInstance().setHomePage(activity, url);
+ BrowserSettings.getInstance().setHomePage(url);
Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
return true;
default:
@@ -636,6 +670,7 @@
item.getPaddingRight(),
item.getPaddingBottom());
item.setFaviconBackground(mFaviconBackground);
+ item.startMarquee();
} else {
item = (HistoryItem) convertView;
}
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index dae838f..8302011 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -21,7 +21,6 @@
import android.app.ActionBar;
import android.os.Bundle;
import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
import android.view.MenuItem;
import java.util.List;
@@ -48,7 +47,7 @@
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
- if (BrowserSettings.DEV_BUILD || BrowserSettings.getInstance().showDebugSettings()) {
+ if (BrowserSettings.getInstance().isDebugEnabled()) {
Header debug = new Header();
debug.title = getText(R.string.pref_development_title);
debug.fragment = DebugPreferencesFragment.class.getName();
@@ -57,16 +56,6 @@
}
@Override
- protected void onPause() {
- super.onPause();
-
- // sync the shared preferences back to BrowserSettings
- BrowserSettings.getInstance().syncSharedPreferences(
- getApplicationContext(),
- PreferenceManager.getDefaultSharedPreferences(this));
- }
-
- @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 9ae2a25..46d47b0 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -1,6 +1,5 @@
-
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -18,409 +17,288 @@
package com.android.browser;
import com.android.browser.homepages.HomeProvider;
+import com.android.browser.provider.BrowserProvider;
import com.android.browser.search.SearchEngine;
import com.android.browser.search.SearchEngines;
import android.app.ActivityManager;
import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.AsyncTask;
+import android.os.Build;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.Browser;
-import android.provider.BrowserContract.Bookmarks;
-import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.WebIconDatabase;
import android.webkit.WebSettings;
import android.webkit.WebSettings.AutoFillProfile;
+import android.webkit.WebSettings.LayoutAlgorithm;
+import android.webkit.WebSettings.PluginState;
+import android.webkit.WebSettings.TextSize;
+import android.webkit.WebSettings.ZoomDensity;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewDatabase;
-import java.util.HashMap;
-import java.util.Observable;
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.WeakHashMap;
-/*
- * Package level class for storing various WebView and Browser settings. To use
- * this class:
- * BrowserSettings s = BrowserSettings.getInstance();
- * s.addObserver(webView.getSettings());
- * s.loadFromDb(context); // Only needed on app startup
- * s.javaScriptEnabled = true;
- * ... // set any other settings
- * s.update(); // this will update all the observers
- *
- * To remove an observer:
- * s.deleteObserver(webView.getSettings());
+/**
+ * Class for managing settings
*/
-public class BrowserSettings extends Observable implements OnSharedPreferenceChangeListener {
- // Private variables for settings
- // NOTE: these defaults need to be kept in sync with the XML
- // until the performance of PreferenceManager.setDefaultValues()
- // is improved.
- // Note: boolean variables are set inside reset function.
- private boolean loadsImagesAutomatically;
- private boolean javaScriptEnabled;
- private WebSettings.PluginState pluginState;
- private boolean javaScriptCanOpenWindowsAutomatically;
- private boolean showSecurityWarnings;
- private boolean rememberPasswords;
- private boolean saveFormData;
- private boolean autoFillEnabled;
- private boolean openInBackground;
- private String defaultTextEncodingName;
- private String homeUrl = "";
- private SearchEngine searchEngine;
- private boolean autoFitPage;
- private boolean loadsPageInOverviewMode;
- private boolean showDebugSettings;
- // HTML5 API flags
- private boolean appCacheEnabled;
- private boolean databaseEnabled;
- private boolean domStorageEnabled;
- private boolean geolocationEnabled;
- private boolean workersEnabled; // only affects V8. JSC does not have a similar setting
- // HTML5 API configuration params
- private long appCacheMaxSize = Long.MAX_VALUE;
- private String appCachePath; // default value set in loadFromDb().
- private String databasePath; // default value set in loadFromDb()
- private String geolocationDatabasePath; // default value set in loadFromDb()
- private WebStorageSizeManager webStorageSizeManager;
+public class BrowserSettings implements OnSharedPreferenceChangeListener,
+ PreferenceKeys {
- private String jsFlags = "";
-
- private final static String TAG = "BrowserSettings";
-
- // Development settings
- public WebSettings.LayoutAlgorithm layoutAlgorithm =
- WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
- private boolean useWideViewPort = true;
- private int userAgent = 0;
- private boolean tracing = false;
- private boolean lightTouch = false;
- private boolean navDump = false;
- private boolean hardwareAccelerated = true;
- private boolean showVisualIndicator = false;
- // Lab settings
- private boolean quickControls = false;
- private boolean useMostVisitedHomepage = false;
- private boolean useInstant = false;
-
- // By default the error console is shown once the user navigates to about:debug.
- // The setting can be then toggled from the settings menu.
- private boolean showConsole = true;
-
- // Private preconfigured values
- private static int minimumFontSize = 1;
- private static int minimumLogicalFontSize = 1;
- private static int defaultFontSize = 16;
- private static int defaultFixedFontSize = 13;
- private static WebSettings.TextSize textSize =
- WebSettings.TextSize.NORMAL;
- private static WebSettings.ZoomDensity zoomDensity =
- WebSettings.ZoomDensity.MEDIUM;
- private static int pageCacheCapacity;
-
-
- private AutoFillProfile autoFillProfile;
- // Default to zero. In the case no profile is set up, the initial
- // value will come from the AutoFillSettingsFragment when the user
- // creates a profile. Otherwise, we'll read the ID of the last used
- // profile from the prefs db.
- private int autoFillActiveProfileId;
- private static final int NO_AUTOFILL_PROFILE_SET = 0;
-
- // Preference keys that are used outside this class
- public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
- public final static String PREF_CLEAR_COOKIES = "privacy_clear_cookies";
- public final static String PREF_CLEAR_HISTORY = "privacy_clear_history";
- public final static String PREF_HOMEPAGE = "homepage";
- public final static String PREF_SEARCH_ENGINE = "search_engine";
- public final static String PREF_CLEAR_FORM_DATA =
- "privacy_clear_form_data";
- public final static String PREF_CLEAR_PASSWORDS =
- "privacy_clear_passwords";
- public final static String PREF_EXTRAS_RESET_DEFAULTS =
- "reset_default_preferences";
- public final static String PREF_DEBUG_SETTINGS = "debug_menu";
- public final static String PREF_WEBSITE_SETTINGS = "website_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";
- public final static String PREF_CLEAR_GEOLOCATION_ACCESS =
- "privacy_clear_geolocation_access";
- public final static String PREF_AUTOFILL_ENABLED = "autofill_enabled";
- public final static String PREF_AUTOFILL_PROFILE = "autofill_profile";
- public final static String PREF_AUTOFILL_ACTIVE_PROFILE_ID = "autofill_active_profile_id";
- public final static String PREF_HARDWARE_ACCEL = "enable_hardware_accel";
- public final static String PREF_VISUAL_INDICATOR = "enable_visual_indicator";
- public final static String PREF_USER_AGENT = "user_agent";
-
- public final static String PREF_QUICK_CONTROLS = "enable_quick_controls";
- public final static String PREF_MOST_VISITED_HOMEPAGE = "use_most_visited_homepage";
- public final static String PREF_PLUGIN_STATE = "plugin_state";
- public final static String PREF_USE_INSTANT = "use_instant_search";
-
- private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; " +
- "U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.16 (KHTML, " +
- "like Gecko) Version/5.0 Safari/533.16";
+ // TODO: Do something with this UserAgent stuff
+ private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
+ "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
+ "Chrome/11.0.696.34 Safari/534.24";
private static final String IPHONE_USERAGENT = "Mozilla/5.0 (iPhone; U; " +
- "CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 " +
- "(KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
+ "CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 " +
+ "(KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7";
private static final String IPAD_USERAGENT = "Mozilla/5.0 (iPad; U; " +
- "CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 " +
- "(KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10";
+ "CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 " +
+ "(KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10";
private static final String FROYO_USERAGENT = "Mozilla/5.0 (Linux; U; " +
- "Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 " +
- "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
+ "Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 " +
+ "(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
- // Value to truncate strings when adding them to a TextView within
- // a ListView
- public final static int MAX_TEXTVIEW_LEN = 80;
+ private static final String HONEYCOMB_USERAGENT = "Mozilla/5.0 (Linux; U; " +
+ "Android 3.1; en-us; Xoom Build/HMJ25) AppleWebKit/534.13 " +
+ "(KHTML, like Gecko) Version/4.0 Safari/534.13";
- public static final String RLZ_PROVIDER = "com.google.android.partnersetup.rlzappprovider";
+ private static final String USER_AGENTS[] = { null,
+ DESKTOP_USERAGENT,
+ IPHONE_USERAGENT,
+ IPAD_USERAGENT,
+ FROYO_USERAGENT,
+ HONEYCOMB_USERAGENT,
+ };
- public static final Uri RLZ_PROVIDER_URI = Uri.parse("content://" + RLZ_PROVIDER + "/");
+ private static BrowserSettings sInstance;
- // Set to true to enable some of the about:debug options
- public static final boolean DEV_BUILD = false;
-
+ private Context mContext;
+ private SharedPreferences mPrefs;
+ private LinkedList<WeakReference<WebSettings>> mManagedSettings;
private Controller mController;
+ private WebStorageSizeManager mWebStorageSizeManager;
+ private AutofillHandler mAutofillHandler;
+ private WeakHashMap<WebSettings, String> mCustomUserAgents;
- // Single instance of the BrowserSettings for use in the Browser app.
- private static BrowserSettings sSingleton;
+ // Cached settings
+ private SearchEngine mSearchEngine;
- // Private map of WebSettings to Observer objects used when deleting an
- // observer.
- private HashMap<WebSettings,Observer> mWebSettingsToObservers =
- new HashMap<WebSettings,Observer>();
+ public static void initialize(final Context context) {
+ sInstance = new BrowserSettings(context);
+ }
- private String mRlzValue = "";
+ public static BrowserSettings getInstance() {
+ return sInstance;
+ }
- private boolean mLoadFromDbComplete;
+ private BrowserSettings(Context context) {
+ mContext = context;
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ if (Build.VERSION.CODENAME.equals("REL")) {
+ // This is a release build, always startup with debug disabled
+ setDebugEnabled(false);
+ }
+ mAutofillHandler = new AutofillHandler(mContext);
+ mManagedSettings = new LinkedList<WeakReference<WebSettings>>();
+ mCustomUserAgents = new WeakHashMap<WebSettings, String>();
+ mWebStorageSizeManager = new WebStorageSizeManager(mContext,
+ new WebStorageSizeManager.StatFsDiskInfo(getAppCachePath()),
+ new WebStorageSizeManager.WebKitAppCacheInfo(getAppCachePath()));
+ mPrefs.registerOnSharedPreferenceChangeListener(this);
+ mAutofillHandler.asyncLoadFromDb();
+ }
- public void waitForLoadFromDbToComplete() {
- synchronized (sSingleton) {
- while (!mLoadFromDbComplete) {
- try {
- sSingleton.wait();
- } catch (InterruptedException e) { }
- }
+ public void setController(Controller controller) {
+ mController = controller;
+ syncSharedSettings();
+
+ if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
+ ((InstantSearchEngine) mSearchEngine).setController(mController);
}
}
- /*
- * An observer wrapper for updating a WebSettings object with the new
- * settings after a call to BrowserSettings.update().
- */
- static class Observer implements java.util.Observer {
- // Private WebSettings object that will be updated.
- private WebSettings mSettings;
-
- Observer(WebSettings w) {
- mSettings = w;
- }
-
- public void update(Observable o, Object arg) {
- BrowserSettings b = (BrowserSettings)o;
- WebSettings s = mSettings;
-
- s.setLayoutAlgorithm(b.layoutAlgorithm);
- if (b.userAgent == 0) {
- // use the default ua string
- s.setUserAgentString(null);
- } else if (b.userAgent == 1) {
- s.setUserAgentString(DESKTOP_USERAGENT);
- } else if (b.userAgent == 2) {
- s.setUserAgentString(IPHONE_USERAGENT);
- } else if (b.userAgent == 3) {
- s.setUserAgentString(IPAD_USERAGENT);
- } else if (b.userAgent == 4) {
- s.setUserAgentString(FROYO_USERAGENT);
- }
- s.setUseWideViewPort(b.useWideViewPort);
- s.setLoadsImagesAutomatically(b.loadsImagesAutomatically);
- s.setJavaScriptEnabled(b.javaScriptEnabled);
- s.setShowVisualIndicator(b.showVisualIndicator);
- s.setPluginState(b.pluginState);
- s.setJavaScriptCanOpenWindowsAutomatically(
- b.javaScriptCanOpenWindowsAutomatically);
- s.setDefaultTextEncodingName(b.defaultTextEncodingName);
- s.setMinimumFontSize(b.minimumFontSize);
- s.setMinimumLogicalFontSize(b.minimumLogicalFontSize);
- s.setDefaultFontSize(b.defaultFontSize);
- 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.setAutoFillEnabled(b.autoFillEnabled);
- s.setSavePassword(b.rememberPasswords);
- s.setLoadWithOverviewMode(b.loadsPageInOverviewMode);
- s.setPageCacheCapacity(pageCacheCapacity);
-
- // WebView inside Browser doesn't want initial focus to be set.
- s.setNeedInitialFocus(false);
- // Browser supports multiple windows
- s.setSupportMultipleWindows(true);
- // enable smooth transition for better performance during panning or
- // zooming
- s.setEnableSmoothTransition(true);
- // disable content url access
- s.setAllowContentAccess(false);
-
- // HTML5 API flags
- s.setAppCacheEnabled(b.appCacheEnabled);
- s.setDatabaseEnabled(b.databaseEnabled);
- s.setDomStorageEnabled(b.domStorageEnabled);
- s.setWorkersEnabled(b.workersEnabled); // This only affects V8.
- s.setGeolocationEnabled(b.geolocationEnabled);
-
- // HTML5 configuration parameters.
- s.setAppCacheMaxSize(b.appCacheMaxSize);
- s.setAppCachePath(b.appCachePath);
- s.setDatabasePath(b.databasePath);
- s.setGeolocationDatabasePath(b.geolocationDatabasePath);
-
- // Active AutoFill profile data.
- s.setAutoFillProfile(b.autoFillProfile);
-
- b.updateTabControlSettings();
+ public void startManagingSettings(WebSettings settings) {
+ synchronized (mManagedSettings) {
+ syncStaticSettings(settings);
+ syncSetting(settings);
+ mManagedSettings.add(new WeakReference<WebSettings>(settings));
}
}
/**
- * Load settings from the browser app's database. It is performed in
- * an AsyncTask as it involves plenty of slow disk IO.
- * NOTE: Strings used for the preferences must match those specified
- * in the various preference XML files.
- * @param ctx A Context object used to query the browser's settings
- * database. If the database exists, the saved settings will be
- * stored in this BrowserSettings object. This will update all
- * observers of this object.
+ * Syncs all the settings that have a Preference UI
*/
- public void asyncLoadFromDb(final Context ctx) {
- mLoadFromDbComplete = false;
- // Run the initial settings load in an AsyncTask as it hits the
- // disk multiple times through SharedPreferences and SQLite. We
- // need to be certain though that this has completed before we start
- // to load pages though, so in the worst case we will block waiting
- // for it to finish in BrowserActivity.onCreate().
- new LoadFromDbTask(ctx).execute();
+ private void syncSetting(WebSettings settings) {
+ settings.setGeolocationEnabled(enableGeolocation());
+ settings.setJavaScriptEnabled(enableJavascript());
+ settings.setLightTouchEnabled(enableLightTouch());
+ settings.setNavDump(enableNavDump());
+ settings.setShowVisualIndicator(enableVisualIndicator());
+ settings.setDefaultTextEncodingName(getDefaultTextEncoding());
+ settings.setDefaultZoom(getDefaultZoom());
+ settings.setMinimumFontSize(getMinimumFontSize());
+ settings.setMinimumLogicalFontSize(getMinimumFontSize());
+ settings.setForceUserScalable(forceEnableUserScalable());
+ settings.setPluginState(getPluginState());
+ settings.setTextSize(getTextSize());
+ settings.setAutoFillEnabled(isAutofillEnabled());
+ settings.setLayoutAlgorithm(getLayoutAlgorithm());
+ settings.setJavaScriptCanOpenWindowsAutomatically(blockPopupWindows());
+ settings.setLoadsImagesAutomatically(loadImages());
+ settings.setLoadWithOverviewMode(loadPageInOverviewMode());
+ settings.setSavePassword(rememberPasswords());
+ settings.setSaveFormData(saveFormdata());
+ settings.setUseWideViewPort(isWideViewport());
+ settings.setAutoFillProfile(getAutoFillProfile());
+
+ String ua = mCustomUserAgents.get(settings);
+ if (enableUseragentSwitcher() && ua != null) {
+ settings.setUserAgentString(ua);
+ } else {
+ settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
+ }
}
- private class LoadFromDbTask extends AsyncTask<Void, Void, Void> {
- private Context mContext;
+ /**
+ * Syncs all the settings that have no UI
+ * These cannot change, so we only need to set them once per WebSettings
+ */
+ private void syncStaticSettings(WebSettings settings) {
+ settings.setDefaultFontSize(16);
+ settings.setDefaultFixedFontSize(13);
+ settings.setPageCacheCapacity(getPageCacheCapacity());
- public LoadFromDbTask(Context context) {
- mContext = context;
+ // WebView inside Browser doesn't want initial focus to be set.
+ settings.setNeedInitialFocus(false);
+ // Browser supports multiple windows
+ settings.setSupportMultipleWindows(true);
+ // enable smooth transition for better performance during panning or
+ // zooming
+ settings.setEnableSmoothTransition(true);
+ // disable content url access
+ settings.setAllowContentAccess(false);
+
+ // HTML5 API flags
+ settings.setAppCacheEnabled(true);
+ settings.setDatabaseEnabled(true);
+ settings.setDomStorageEnabled(true);
+ settings.setWorkersEnabled(true); // This only affects V8.
+
+ // HTML5 configuration parametersettings.
+ settings.setAppCacheMaxSize(mWebStorageSizeManager.getAppCacheMaxSize());
+ settings.setAppCachePath(getAppCachePath());
+ settings.setDatabasePath(mContext.getDir("databases", 0).getPath());
+ settings.setGeolocationDatabasePath(mContext.getDir("geolocation", 0).getPath());
+ }
+
+ private void syncSharedSettings() {
+ CookieManager.getInstance().setAcceptCookie(acceptCookies());
+ if (mController != null) {
+ mController.setShouldShowErrorConsole(enableJavascriptConsole());
}
+ }
- protected Void doInBackground(Void... unused) {
- SharedPreferences p =
- PreferenceManager.getDefaultSharedPreferences(mContext);
- // Set the default value for the Application Caches path.
- appCachePath = mContext.getDir("appcache", 0).getPath();
- // Determine the maximum size of the application cache.
- webStorageSizeManager = new WebStorageSizeManager(
- mContext,
- new WebStorageSizeManager.StatFsDiskInfo(appCachePath),
- new WebStorageSizeManager.WebKitAppCacheInfo(appCachePath));
- appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
- // Set the default value for the Database path.
- databasePath = mContext.getDir("databases", 0).getPath();
- // Set the default value for the Geolocation database path.
- geolocationDatabasePath = mContext.getDir("geolocation", 0).getPath();
-
- if (p.getString(PREF_HOMEPAGE, null) == null) {
- // No home page preferences is set, set it to default.
- setHomePage(mContext, getFactoryResetHomeUrl(mContext));
+ private void syncManagedSettings() {
+ syncSharedSettings();
+ synchronized (mManagedSettings) {
+ Iterator<WeakReference<WebSettings>> iter = mManagedSettings.iterator();
+ while (iter.hasNext()) {
+ WeakReference<WebSettings> ref = iter.next();
+ WebSettings settings = ref.get();
+ if (settings == null) {
+ iter.remove();
+ continue;
+ }
+ syncSetting(settings);
}
+ }
+ }
- // the cost of one cached page is ~3M (measured using nytimes.com). For
- // low end devices, we only cache one page. For high end devices, we try
- // to cache more pages, currently choose 5.
- ActivityManager am = (ActivityManager) mContext
- .getSystemService(Context.ACTIVITY_SERVICE);
- if (am.getMemoryClass() > 16) {
- pageCacheCapacity = 5;
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ syncManagedSettings();
+ if (PREF_SEARCH_ENGINE.equals(key)) {
+ updateSearchEngine(false);
+ }
+ if (PREF_USE_INSTANT_SEARCH.equals(key)) {
+ updateSearchEngine(true);
+ }
+ if (PREF_FULLSCREEN.equals(key)) {
+ if (mController.getUi() != null) {
+ mController.getUi().setFullscreen(useFullscreen());
+ }
+ }
+ }
+
+ static String getFactoryResetHomeUrl(Context context) {
+ String url = context.getResources().getString(R.string.homepage_base);
+ if (url.indexOf("{CID}") != -1) {
+ url = url.replace("{CID}",
+ BrowserProvider.getClientId(context.getContentResolver()));
+ }
+ return url;
+ }
+
+ public LayoutAlgorithm getLayoutAlgorithm() {
+ LayoutAlgorithm layoutAlgorithm = LayoutAlgorithm.NORMAL;
+ if (autofitPages()) {
+ layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
+ }
+ if (isDebugEnabled()) {
+ if (isSmallScreen()) {
+ layoutAlgorithm = LayoutAlgorithm.SINGLE_COLUMN;
} else {
- pageCacheCapacity = 1;
+ if (isNormalLayout()) {
+ layoutAlgorithm = LayoutAlgorithm.NORMAL;
+ } else {
+ layoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
+ }
}
+ }
+ return layoutAlgorithm;
+ }
- // Read the last active AutoFill profile id.
- autoFillActiveProfileId = p.getInt(
- PREF_AUTOFILL_ACTIVE_PROFILE_ID, autoFillActiveProfileId);
-
- // Load the autofill profile data from the database. We use a database separate
- // to the browser preference DB to make it easier to support multiple profiles
- // and switching between them.
- AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
- Cursor c = autoFillDb.getProfile(autoFillActiveProfileId);
-
- if (c.getCount() > 0) {
- c.moveToFirst();
-
- String fullName = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.FULL_NAME));
- String email = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
- String company = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.COMPANY_NAME));
- String addressLine1 = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
- String addressLine2 = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
- String city = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.CITY));
- String state = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.STATE));
- String zip = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.ZIP_CODE));
- String country = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.COUNTRY));
- String phone = c.getString(c.getColumnIndex(
- AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
- autoFillProfile = new AutoFillProfile(autoFillActiveProfileId,
- fullName, email, company, addressLine1, addressLine2, city,
- state, zip, country, phone);
- }
- c.close();
- autoFillDb.close();
-
- // PreferenceManager.setDefaultValues is TOO SLOW, need to manually keep
- // the defaults in sync
- p.registerOnSharedPreferenceChangeListener(BrowserSettings.this);
- syncSharedPreferences(mContext, p);
-
- synchronized (sSingleton) {
- mLoadFromDbComplete = true;
- sSingleton.notify();
- }
- return null;
+ // TODO: Cache
+ public int getPageCacheCapacity() {
+ // the cost of one cached page is ~3M (measured using nytimes.com). For
+ // low end devices, we only cache one page. For high end devices, we try
+ // to cache more pages, currently choose 5.
+ if (ActivityManager.staticGetMemoryClass() > 16) {
+ return 5;
+ } else {
+ return 1;
}
}
- private void updateSearchEngine(Context ctx, String searchEngineName, boolean force) {
- if (force || searchEngine == null ||
- !searchEngine.getName().equals(searchEngineName)) {
- if (searchEngine != null) {
- if (searchEngine.supportsVoiceSearch()) {
+ public WebStorageSizeManager getWebStorageSizeManager() {
+ return mWebStorageSizeManager;
+ }
+
+ // TODO: Cache
+ private String getAppCachePath() {
+ return mContext.getDir("appcache", 0).getPath();
+ }
+
+ private void updateSearchEngine(boolean force) {
+ String searchEngineName = getSearchEngineName();
+ if (force || mSearchEngine == null ||
+ !mSearchEngine.getName().equals(searchEngineName)) {
+ if (mSearchEngine != null) {
+ if (mSearchEngine.supportsVoiceSearch()) {
// One or more tabs could have been in voice search mode.
// Clear it, since the new SearchEngine may not support
// it, or may handle it differently.
@@ -428,302 +306,32 @@
mController.getTabControl().getTab(i).revertVoiceSearchMode();
}
}
- searchEngine.close();
+ mSearchEngine.close();
}
- searchEngine = SearchEngines.get(ctx, searchEngineName);
+ mSearchEngine = SearchEngines.get(mContext, searchEngineName);
- if (mController != null && (searchEngine instanceof InstantSearchEngine)) {
- ((InstantSearchEngine) searchEngine).setController(mController);
+ if (mController != null && (mSearchEngine instanceof InstantSearchEngine)) {
+ ((InstantSearchEngine) mSearchEngine).setController(mController);
}
}
}
- /* package */ void syncSharedPreferences(Context ctx, SharedPreferences p) {
-
- homeUrl =
- p.getString(PREF_HOMEPAGE, homeUrl);
-
- useInstant = p.getBoolean(PREF_USE_INSTANT, useInstant);
- String searchEngineName = p.getString(PREF_SEARCH_ENGINE,
- SearchEngine.GOOGLE);
- updateSearchEngine(ctx, searchEngineName, false);
-
- loadsImagesAutomatically = p.getBoolean("load_images",
- loadsImagesAutomatically);
- javaScriptEnabled = p.getBoolean("enable_javascript",
- javaScriptEnabled);
- pluginState = WebSettings.PluginState.valueOf(
- p.getString(PREF_PLUGIN_STATE, pluginState.name()));
- javaScriptCanOpenWindowsAutomatically = !p.getBoolean(
- "block_popup_windows",
- !javaScriptCanOpenWindowsAutomatically);
- showSecurityWarnings = p.getBoolean("show_security_warnings",
- showSecurityWarnings);
- rememberPasswords = p.getBoolean("remember_passwords",
- rememberPasswords);
- saveFormData = p.getBoolean("save_formdata",
- saveFormData);
- autoFillEnabled = p.getBoolean("autofill_enabled", autoFillEnabled);
- boolean accept_cookies = p.getBoolean("accept_cookies",
- CookieManager.getInstance().acceptCookie());
- CookieManager.getInstance().setAcceptCookie(accept_cookies);
- openInBackground = p.getBoolean("open_in_background", openInBackground);
- 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);
- loadsPageInOverviewMode = p.getBoolean("load_page",
- loadsPageInOverviewMode);
- useWideViewPort = true; // use wide view port for either setting
- if (autoFitPage) {
- layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
- } else {
- layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
- }
- defaultTextEncodingName =
- p.getString(PREF_DEFAULT_TEXT_ENCODING,
- defaultTextEncodingName);
-
- showDebugSettings =
- p.getBoolean(PREF_DEBUG_SETTINGS, showDebugSettings);
- // Debug menu items have precidence if the menu is visible
- if (showDebugSettings) {
- boolean small_screen = p.getBoolean("small_screen",
- layoutAlgorithm ==
- WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
- if (small_screen) {
- layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN;
- } else {
- boolean normal_layout = p.getBoolean("normal_layout",
- layoutAlgorithm == WebSettings.LayoutAlgorithm.NORMAL);
- if (normal_layout) {
- layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
- } else {
- layoutAlgorithm =
- WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
- }
- }
- useWideViewPort = p.getBoolean("wide_viewport", useWideViewPort);
- tracing = p.getBoolean("enable_tracing", tracing);
- lightTouch = p.getBoolean("enable_light_touch", lightTouch);
- navDump = p.getBoolean("enable_nav_dump", navDump);
- showVisualIndicator = p.getBoolean(PREF_VISUAL_INDICATOR, showVisualIndicator);
- }
-
- quickControls = p.getBoolean(PREF_QUICK_CONTROLS, quickControls);
- useMostVisitedHomepage = p.getBoolean(PREF_MOST_VISITED_HOMEPAGE, useMostVisitedHomepage);
-
- // Only set these if this is a dev build or debug is enabled
- if (DEV_BUILD || showDebugSettings()) {
- userAgent = Integer.parseInt(p.getString(PREF_USER_AGENT, "0"));
- hardwareAccelerated = p.getBoolean(PREF_HARDWARE_ACCEL, hardwareAccelerated);
- }
-
- // JS flags is loaded from DB even if showDebugSettings is false,
- // so that it can be set once and be effective all the time.
- jsFlags = p.getString("js_engine_flags", "");
-
- // Read the setting for showing/hiding the JS Console always so that should the
- // user enable debug settings, we already know if we should show the console.
- // The user will never see the console unless they navigate to about:debug,
- // regardless of the setting we read here. This setting is only used after debug
- // is enabled.
- showConsole = p.getBoolean("javascript_console", showConsole);
-
- // HTML5 API flags
- appCacheEnabled = p.getBoolean("enable_appcache", appCacheEnabled);
- databaseEnabled = p.getBoolean("enable_database", databaseEnabled);
- domStorageEnabled = p.getBoolean("enable_domstorage", domStorageEnabled);
- geolocationEnabled = p.getBoolean("enable_geolocation", geolocationEnabled);
- workersEnabled = p.getBoolean("enable_workers", workersEnabled);
-
- update();
- }
-
- public String getHomePage() {
- if (useMostVisitedHomepage) {
- return HomeProvider.MOST_VISITED;
- }
- return homeUrl;
- }
-
public SearchEngine getSearchEngine() {
- return searchEngine;
- }
-
- public String getJsFlags() {
- return jsFlags;
- }
-
- public WebStorageSizeManager getWebStorageSizeManager() {
- return webStorageSizeManager;
- }
-
- public void setHomePage(Context context, String url) {
- Editor ed = PreferenceManager.
- getDefaultSharedPreferences(context).edit();
- ed.putString(PREF_HOMEPAGE, url);
- ed.apply();
- homeUrl = url;
- }
-
- public WebSettings.TextSize getTextSize() {
- return textSize;
- }
-
- public WebSettings.ZoomDensity getDefaultZoom() {
- return zoomDensity;
- }
-
- public boolean openInBackground() {
- return openInBackground;
- }
-
- public boolean showSecurityWarnings() {
- return showSecurityWarnings;
- }
-
- public boolean isTracing() {
- return tracing;
- }
-
- public boolean isLightTouch() {
- return lightTouch;
- }
-
- public boolean isNavDump() {
- return navDump;
- }
-
- public boolean isHardwareAccelerated() {
- return hardwareAccelerated;
- }
-
- public boolean showVisualIndicator() {
- return showVisualIndicator;
- }
-
- public boolean useQuickControls() {
- return quickControls;
- }
-
- public boolean useMostVisitedHomepage() {
- return useMostVisitedHomepage;
- }
-
- public boolean useInstant() {
- return useInstant;
- }
-
- public boolean showDebugSettings() {
- return showDebugSettings;
- }
-
- public void toggleDebugSettings(Context context) {
- showDebugSettings = !showDebugSettings;
- navDump = showDebugSettings;
- syncSharedPreferences(context,
- PreferenceManager.getDefaultSharedPreferences(context));
- update();
- }
-
- public void setAutoFillProfile(Context ctx, AutoFillProfile profile, Message msg) {
- if (profile != null) {
- setActiveAutoFillProfileId(ctx, profile.getUniqueId());
- // Update the AutoFill DB with the new profile.
- new SaveProfileToDbTask(ctx, msg).execute(profile);
- } else {
- // Delete the current profile.
- if (autoFillProfile != null) {
- new DeleteProfileFromDbTask(ctx, msg).execute(autoFillProfile.getUniqueId());
- setActiveAutoFillProfileId(ctx, NO_AUTOFILL_PROFILE_SET);
- }
+ if (mSearchEngine == null) {
+ updateSearchEngine(false);
}
- autoFillProfile = profile;
+ return mSearchEngine;
}
- public AutoFillProfile getAutoFillProfile() {
- return autoFillProfile;
+ public boolean isDebugEnabled() {
+ return mPrefs.getBoolean(PREF_DEBUG_MENU, false);
}
- private void setActiveAutoFillProfileId(Context context, int activeProfileId) {
- autoFillActiveProfileId = activeProfileId;
- Editor ed = PreferenceManager.
- getDefaultSharedPreferences(context).edit();
- ed.putInt(PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
- ed.apply();
+ public void setDebugEnabled(boolean value) {
+ mPrefs.edit().putBoolean(PREF_DEBUG_MENU, value).apply();
}
- /* package */ void disableAutoFill(Context ctx) {
- autoFillEnabled = false;
- Editor ed = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
- ed.putBoolean(PREF_AUTOFILL_ENABLED, false);
- ed.apply();
- }
-
- /**
- * Add a WebSettings object to the list of observers that will be updated
- * when update() is called.
- *
- * @param s A WebSettings object that is strictly tied to the life of a
- * WebView.
- */
- public Observer addObserver(WebSettings s) {
- Observer old = mWebSettingsToObservers.get(s);
- if (old != null) {
- super.deleteObserver(old);
- }
- Observer o = new Observer(s);
- mWebSettingsToObservers.put(s, o);
- super.addObserver(o);
- return o;
- }
-
- /**
- * Delete the given WebSettings observer from the list of observers.
- * @param s The WebSettings object to be deleted.
- */
- public void deleteObserver(WebSettings s) {
- Observer o = mWebSettingsToObservers.get(s);
- if (o != null) {
- mWebSettingsToObservers.remove(s);
- super.deleteObserver(o);
- }
- }
-
- /*
- * Application level method for obtaining a single app instance of the
- * BrowserSettings.
- */
- public static BrowserSettings getInstance() {
- if (sSingleton == null ) {
- sSingleton = new BrowserSettings();
- }
- return sSingleton;
- }
-
- /*
- * Package level method for associating the BrowserSettings with TabControl
- */
- /* package */void setController(Controller ctrl) {
- mController = ctrl;
- updateTabControlSettings();
-
- if (mController != null && (searchEngine instanceof InstantSearchEngine)) {
- ((InstantSearchEngine) searchEngine).setController(mController);
- }
- }
-
- /*
- * Update all the observers of the object.
- */
- /*package*/ void update() {
- setChanged();
- notifyObservers();
- }
-
- /*package*/ void clearCache(Context context) {
+ public void clearCache() {
WebIconDatabase.getInstance().removeAllIcons();
if (mController != null) {
WebView current = mController.getCurrentWebView();
@@ -733,18 +341,18 @@
}
}
- /*package*/ void clearCookies(Context context) {
+ public void clearCookies() {
CookieManager.getInstance().removeAllCookie();
}
- /* package */void clearHistory(Context context) {
- ContentResolver resolver = context.getContentResolver();
+ public void clearHistory() {
+ ContentResolver resolver = mContext.getContentResolver();
Browser.clearHistory(resolver);
Browser.clearSearches(resolver);
}
- /* package */ void clearFormData(Context context) {
- WebViewDatabase.getInstance(context).clearFormData();
+ public void clearFormData() {
+ WebViewDatabase.getInstance(mContext).clearFormData();
if (mController!= null) {
WebView currentTopView = mController.getCurrentTopWebView();
if (currentTopView != null) {
@@ -753,260 +361,277 @@
}
}
- /*package*/ void clearPasswords(Context context) {
- WebViewDatabase db = WebViewDatabase.getInstance(context);
+ public void clearPasswords() {
+ WebViewDatabase db = WebViewDatabase.getInstance(mContext);
db.clearUsernamePassword();
db.clearHttpAuthUsernamePassword();
}
- private void updateTabControlSettings() {
- // Enable/disable the error console.
- mController.setShouldShowErrorConsole(
- showDebugSettings && showConsole);
- }
-
- /*package*/ void clearDatabases(Context context) {
+ public void clearDatabases() {
WebStorage.getInstance().deleteAllData();
}
- /*package*/ void clearLocationAccess(Context context) {
+ public void clearLocationAccess() {
GeolocationPermissions.getInstance().clearAll();
}
- /*package*/ void resetDefaultPreferences(Context ctx) {
- reset();
- SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(ctx);
- p.edit().clear().apply();
- PreferenceManager.setDefaultValues(ctx, R.xml.general_preferences, true);
- PreferenceManager.setDefaultValues(ctx, R.xml.privacy_security_preferences, true);
- PreferenceManager.setDefaultValues(ctx, R.xml.advanced_preferences, true);
- // reset homeUrl
- setHomePage(ctx, getFactoryResetHomeUrl(ctx));
- // reset appcache max size
- appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize();
- setActiveAutoFillProfileId(ctx, NO_AUTOFILL_PROFILE_SET);
+ public void resetDefaultPreferences() {
+ mPrefs.edit().clear().apply();
+ syncManagedSettings();
}
- /*package*/ static String getFactoryResetHomeUrl(Context context) {
- String url = context.getResources().getString(R.string.homepage_base);
- if (url.indexOf("{CID}") != -1) {
- url = url.replace("{CID}",
- BrowserProvider.getClientId(context.getContentResolver()));
+ public AutoFillProfile getAutoFillProfile() {
+ mAutofillHandler.waitForLoad();
+ return mAutofillHandler.getAutoFillProfile();
+ }
+
+ public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
+ mAutofillHandler.waitForLoad();
+ mAutofillHandler.setAutoFillProfile(profile, msg);
+ }
+
+ public void toggleDebugSettings() {
+ setDebugEnabled(!isDebugEnabled());
+ }
+
+ public boolean hasDesktopUseragent(WebView view) {
+ return view != null && mCustomUserAgents.get(view.getSettings()) != null;
+ }
+
+ public void toggleDesktopUseragent(WebView view) {
+ if (view == null) {
+ return;
}
- return url;
- }
-
- // Private constructor that does nothing.
- private BrowserSettings() {
- reset();
- }
-
- private void reset() {
- // Private variables for settings
- // NOTE: these defaults need to be kept in sync with the XML
- // until the performance of PreferenceManager.setDefaultValues()
- // is improved.
- loadsImagesAutomatically = true;
- javaScriptEnabled = true;
- pluginState = WebSettings.PluginState.ON;
- javaScriptCanOpenWindowsAutomatically = false;
- showSecurityWarnings = true;
- rememberPasswords = true;
- saveFormData = true;
- autoFillEnabled = true;
- openInBackground = false;
- autoFitPage = true;
- loadsPageInOverviewMode = true;
- showDebugSettings = false;
- // HTML5 API flags
- appCacheEnabled = true;
- databaseEnabled = true;
- domStorageEnabled = true;
- geolocationEnabled = true;
- workersEnabled = true; // only affects V8. JSC does not have a similar setting
- }
-
- private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
- Context mContext;
- AutoFillProfileDatabase mAutoFillProfileDb;
- Message mCompleteMessage;
-
- public AutoFillProfileDbTask(Context ctx, Message msg) {
- mContext = ctx;
- mCompleteMessage = msg;
- }
-
- protected void onPostExecute(Void result) {
- if (mCompleteMessage != null) {
- mCompleteMessage.sendToTarget();
- }
- mAutoFillProfileDb.close();
- }
-
- abstract protected Void doInBackground(T... values);
- }
-
-
- private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
- public SaveProfileToDbTask(Context ctx, Message msg) {
- super(ctx, msg);
- }
-
- protected Void doInBackground(AutoFillProfile... values) {
- mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
- assert autoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
- AutoFillProfile newProfile = values[0];
- mAutoFillProfileDb.addOrUpdateProfile(autoFillActiveProfileId, newProfile);
- return null;
+ WebSettings settings = view.getSettings();
+ if (mCustomUserAgents.get(settings) != null) {
+ mCustomUserAgents.remove(settings);
+ settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
+ } else {
+ mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
+ settings.setUserAgentString(DESKTOP_USERAGENT);
}
}
- private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
- public DeleteProfileFromDbTask(Context ctx, Message msg) {
- super(ctx, msg);
- }
+ // -----------------------------
+ // getter/setters for accessibility_preferences.xml
+ // -----------------------------
- protected Void doInBackground(Integer... values) {
- mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
- int id = values[0];
- assert id > 0;
- mAutoFillProfileDb.dropProfile(id);
- return null;
- }
+ // TODO: Cache
+ public TextSize getTextSize() {
+ String textSize = mPrefs.getString(PREF_TEXT_SIZE, "NORMAL");
+ return TextSize.valueOf(textSize);
}
- @Override
- public void onSharedPreferenceChanged(
- SharedPreferences p, String key) {
- if (PREF_HARDWARE_ACCEL.equals(key)) {
- hardwareAccelerated = p.getBoolean(PREF_HARDWARE_ACCEL, hardwareAccelerated);
- } else if (PREF_VISUAL_INDICATOR.equals(key)) {
- showVisualIndicator = p.getBoolean(PREF_VISUAL_INDICATOR, showVisualIndicator);
- } else if (PREF_USER_AGENT.equals(key)) {
- userAgent = Integer.parseInt(p.getString(PREF_USER_AGENT, "0"));
- update();
- } else if (PREF_QUICK_CONTROLS.equals(key)) {
- quickControls = p.getBoolean(PREF_QUICK_CONTROLS, quickControls);
- } else if (PREF_MOST_VISITED_HOMEPAGE.equals(key)) {
- useMostVisitedHomepage = p.getBoolean(PREF_MOST_VISITED_HOMEPAGE, useMostVisitedHomepage);
- } else if (PREF_USE_INSTANT.equals(key)) {
- useInstant = p.getBoolean(PREF_USE_INSTANT, useInstant);
- updateSearchEngine(mController.getActivity(), SearchEngine.GOOGLE, true);
- } else if (PREF_SEARCH_ENGINE.equals(key)) {
- final String searchEngineName = p.getString(PREF_SEARCH_ENGINE,
- SearchEngine.GOOGLE);
- updateSearchEngine(mController.getActivity(), searchEngineName, false);
- }
+ public int getMinimumFontSize() {
+ return mPrefs.getInt(PREF_MIN_FONT_SIZE, 1);
}
- /*package*/ String getRlzValue() {
- return mRlzValue;
+ public boolean forceEnableUserScalable() {
+ return mPrefs.getBoolean(PREF_FORCE_USERSCALABLE, false);
}
- /*package*/ void updateRlzValues(Context context) {
- // Use AsyncTask because this queries both RlzProvider and Bookmarks URIs
- new RlzUpdateTask(context).execute();
+ // -----------------------------
+ // getter/setters for advanced_preferences.xml
+ // -----------------------------
+
+ public String getSearchEngineName() {
+ return mPrefs.getString(PREF_SEARCH_ENGINE, SearchEngine.GOOGLE);
}
- private class RlzUpdateTask extends AsyncTask<Void, Void, Void> {
- private final Context context;
-
- public RlzUpdateTask(Context context) {
- this.context = context;
- }
-
- @Override
- protected Void doInBackground(Void...unused) {
- String rlz = retrieveRlzValue(context);
- if (!rlz.isEmpty()) {
- mRlzValue = rlz;
- updateHomePageRlzParameter(context);
- updateBookmarksRlzParameter(context);
- }
- return null;
- }
+ public boolean openInBackground() {
+ return mPrefs.getBoolean(PREF_OPEN_IN_BACKGROUND, false);
}
- // Update RLZ value if present in Home page
- private void updateHomePageRlzParameter(Context context) {
- Uri uri = Uri.parse(homeUrl);
- if ((uri.getQueryParameter("rlz") != null) && UrlUtils.isGoogleUri(uri)) {
- String newHomeUrl = updateRlzParameter(homeUrl);
- if (!homeUrl.equals(newHomeUrl)) {
- setHomePage(context, newHomeUrl);
- }
- }
+ public boolean enableJavascript() {
+ return mPrefs.getBoolean(PREF_ENABLE_JAVASCRIPT, true);
}
- // Update RLZ value if present in bookmarks
- private void updateBookmarksRlzParameter(Context context) {
- Cursor cur = null;
- try {
- cur = context.getContentResolver().query(Bookmarks.CONTENT_URI_DEFAULT_FOLDER,
- new String[] { Bookmarks._ID, Bookmarks.URL }, "url LIKE '%rlz=%'", null, null);
- if ((cur == null) || (cur.getCount() == 0)) {
- return;
- }
- for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
- long id = cur.getLong(0);
- String url = cur.getString(1);
- if ((url == null) || url.isEmpty()) {
- continue;
- }
-
- Uri uri = Uri.parse(url);
- if ((uri.getQueryParameter("rlz") != null) && UrlUtils.isGoogleUri(uri)) {
- String newUrl = updateRlzParameter(url);
- if (!url.equals(newUrl)) {
- ContentValues values = new ContentValues();
- values.put(Bookmarks.URL, newUrl);
- Uri bookmarkUri = ContentUris.withAppendedId(
- BookmarkUtils.getBookmarksUri(context), id);
- context.getContentResolver().update(bookmarkUri, values, null, null);
- }
- }
- }
- } finally {
- if (cur != null) {
- cur.close();
- }
- }
+ // TODO: Cache
+ public PluginState getPluginState() {
+ String state = mPrefs.getString(PREF_PLUGIN_STATE, "ON");
+ return PluginState.valueOf(state);
}
- private String updateRlzParameter(String url) {
- Uri uri = Uri.parse(url);
- String oldRlz = uri.getQueryParameter("rlz");
- if (oldRlz != null) {
- return url.replace("rlz=" + oldRlz, "rlz=" + mRlzValue);
- }
- return url;
+ // TODO: Cache
+ public ZoomDensity getDefaultZoom() {
+ String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
+ return ZoomDensity.valueOf(zoom);
}
- // Retrieve the RLZ value from the Rlz Provider
- private static String retrieveRlzValue(Context context) {
- String rlz = "";
- PackageManager pm = context.getPackageManager();
- if (pm.resolveContentProvider(RLZ_PROVIDER, 0) == null) {
- return rlz;
- }
-
- String ap = context.getResources().getString(R.string.rlz_access_point);
- if (ap.isEmpty()) {
- return rlz;
- }
-
- Uri rlzUri = Uri.withAppendedPath(RLZ_PROVIDER_URI, ap);
- Cursor cur = null;
- try {
- cur = context.getContentResolver().query(rlzUri, null, null, null, null);
- if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
- rlz = cur.getString(0);
- }
- } finally {
- if (cur != null) {
- cur.close();
- }
- }
- return rlz;
+ public boolean loadPageInOverviewMode() {
+ return mPrefs.getBoolean(PREF_LOAD_PAGE, true);
}
+
+ public boolean autofitPages() {
+ return mPrefs.getBoolean(PREF_AUTOFIT_PAGES, true);
+ }
+
+ public boolean blockPopupWindows() {
+ return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true);
+ }
+
+ public boolean loadImages() {
+ return mPrefs.getBoolean(PREF_LOAD_IMAGES, true);
+ }
+
+ public String getDefaultTextEncoding() {
+ return mPrefs.getString(PREF_DEFAULT_TEXT_ENCODING, null);
+ }
+
+ // -----------------------------
+ // getter/setters for general_preferences.xml
+ // -----------------------------
+
+ public String getHomePage() {
+ if (useMostVisitedHomepage()) {
+ return HomeProvider.MOST_VISITED;
+ }
+ return mPrefs.getString(PREF_HOMEPAGE, getFactoryResetHomeUrl(mContext));
+ }
+
+ public void setHomePage(String value) {
+ mPrefs.edit().putString(PREF_HOMEPAGE, value).apply();
+ }
+
+ public boolean isAutofillEnabled() {
+ return mPrefs.getBoolean(PREF_AUTOFILL_ENABLED, true);
+ }
+
+ public void setAutofillEnabled(boolean value) {
+ mPrefs.edit().putBoolean(PREF_AUTOFILL_ENABLED, value).apply();
+ }
+
+ // -----------------------------
+ // getter/setters for debug_preferences.xml
+ // -----------------------------
+
+ public boolean isHardwareAccelerated() {
+ if (!isDebugEnabled()) {
+ return true;
+ }
+ return mPrefs.getBoolean(PREF_ENABLE_HARDWARE_ACCEL, true);
+ }
+
+ public int getUserAgent() {
+ if (!isDebugEnabled()) {
+ return 0;
+ }
+ return Integer.parseInt(mPrefs.getString(PREF_USER_AGENT, "0"));
+ }
+
+ // -----------------------------
+ // getter/setters for hidden_debug_preferences.xml
+ // -----------------------------
+
+ public boolean enableVisualIndicator() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_ENABLE_VISUAL_INDICATOR, false);
+ }
+
+ public boolean enableJavascriptConsole() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_JAVASCRIPT_CONSOLE, true);
+ }
+
+ public boolean isSmallScreen() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_SMALL_SCREEN, false);
+ }
+
+ public boolean isWideViewport() {
+ if (!isDebugEnabled()) {
+ return true;
+ }
+ return mPrefs.getBoolean(PREF_WIDE_VIEWPORT, true);
+ }
+
+ public boolean isNormalLayout() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_NORMAL_LAYOUT, false);
+ }
+
+ public boolean isTracing() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_ENABLE_TRACING, false);
+ }
+
+ public boolean enableLightTouch() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_ENABLE_LIGHT_TOUCH, false);
+ }
+
+ public boolean enableNavDump() {
+ if (!isDebugEnabled()) {
+ return false;
+ }
+ return mPrefs.getBoolean(PREF_ENABLE_NAV_DUMP, false);
+ }
+
+ public String getJsEngineFlags() {
+ if (!isDebugEnabled()) {
+ return "";
+ }
+ return mPrefs.getString(PREF_JS_ENGINE_FLAGS, "");
+ }
+
+ // -----------------------------
+ // getter/setters for lab_preferences.xml
+ // -----------------------------
+
+ public boolean useQuickControls() {
+ return mPrefs.getBoolean(PREF_ENABLE_QUICK_CONTROLS, false);
+ }
+
+ public boolean useMostVisitedHomepage() {
+ return mPrefs.getBoolean(PREF_USE_MOST_VISITED_HOMEPAGE, false);
+ }
+
+ public boolean useInstantSearch() {
+ return mPrefs.getBoolean(PREF_USE_INSTANT_SEARCH, false);
+ }
+
+ public boolean useFullscreen() {
+ return mPrefs.getBoolean(PREF_FULLSCREEN, false);
+ }
+
+ public boolean enableUseragentSwitcher() {
+ return mPrefs.getBoolean(PREF_ENABLE_USERAGENT_SWITCHER, false);
+ }
+
+ // -----------------------------
+ // getter/setters for privacy_security_preferences.xml
+ // -----------------------------
+
+ public boolean showSecurityWarnings() {
+ return mPrefs.getBoolean(PREF_SHOW_SECURITY_WARNINGS, true);
+ }
+
+ public boolean acceptCookies() {
+ return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true);
+ }
+
+ public boolean saveFormdata() {
+ return mPrefs.getBoolean(PREF_SAVE_FORMDATA, true);
+ }
+
+ public boolean enableGeolocation() {
+ return mPrefs.getBoolean(PREF_ENABLE_GEOLOCATION, true);
+ }
+
+ public boolean rememberPasswords() {
+ return mPrefs.getBoolean(PREF_REMEMBER_PASSWORDS, true);
+ }
+
}
diff --git a/src/com/android/browser/ScrollWebView.java b/src/com/android/browser/BrowserWebView.java
similarity index 73%
rename from src/com/android/browser/ScrollWebView.java
rename to src/com/android/browser/BrowserWebView.java
index 8c89e51..5a40b3c 100644
--- a/src/com/android/browser/ScrollWebView.java
+++ b/src/com/android/browser/BrowserWebView.java
@@ -18,24 +18,29 @@
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebView;
+import com.android.browser.NavTabView.WebProxyView;
+
import java.util.Map;
/**
* Manage WebView scroll events
*/
-public class ScrollWebView extends WebView implements Runnable {
+public class BrowserWebView extends WebView implements Runnable {
private ScrollListener mScrollListener;
private boolean mIsCancelled;
private boolean mBackgroundRemoved = false;
private boolean mUserInitiated = false;
private TitleBarBase mTitleBar;
- private Bitmap mBitmap;
+ private int mCaptureSize;
+ private Bitmap mCapture;
+ private WebProxyView mProxyView;
/**
* @param context
@@ -43,7 +48,7 @@
* @param defStyle
* @param javascriptInterfaces
*/
- public ScrollWebView(Context context, AttributeSet attrs, int defStyle,
+ public BrowserWebView(Context context, AttributeSet attrs, int defStyle,
Map<String, Object> javascriptInterfaces, boolean privateBrowsing) {
super(context, attrs, defStyle, javascriptInterfaces, privateBrowsing);
}
@@ -53,24 +58,45 @@
* @param attrs
* @param defStyle
*/
- public ScrollWebView(
+ public BrowserWebView(
Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
super(context, attrs, defStyle, privateBrowsing);
+ init();
}
/**
* @param context
* @param attrs
*/
- public ScrollWebView(Context context, AttributeSet attrs) {
+ public BrowserWebView(Context context, AttributeSet attrs) {
super(context, attrs);
+ init();
}
/**
* @param context
*/
- public ScrollWebView(Context context) {
+ public BrowserWebView(Context context) {
super(context);
+ init();
+ }
+
+ private void init() {
+ mCaptureSize = mContext.getResources().getDimensionPixelSize(R.dimen.tab_capture_size);
+ mCapture = Bitmap.createBitmap(mCaptureSize, mCaptureSize,
+ Bitmap.Config.RGB_565);
+ }
+
+ protected void setProxyView(WebProxyView p) {
+ mProxyView = p;
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ if (mProxyView != null) {
+ mProxyView.invalidate();
+ }
}
@Override
@@ -140,6 +166,18 @@
public void onScroll(int visibleTitleHeight, boolean userInitiated);
}
+ protected Bitmap capture() {
+ if (mCapture == null) return null;
+ Canvas c = new Canvas(mCapture);
+ final int left = getScrollX();
+ final int top = getScrollY() + getVisibleTitleHeight();
+ c.translate(-left, -top);
+ float scale = mCaptureSize / (float) Math.max(getWidth(), getHeight());
+ c.scale(scale, scale, left, top);
+ onDraw(c);
+ return mCapture;
+ }
+
@Override
protected void onDraw(android.graphics.Canvas c) {
super.onDraw(c);
diff --git a/src/com/android/browser/BrowserYesNoPreference.java b/src/com/android/browser/BrowserYesNoPreference.java
index caea092..d5d5205 100644
--- a/src/com/android/browser/BrowserYesNoPreference.java
+++ b/src/com/android/browser/BrowserYesNoPreference.java
@@ -35,25 +35,25 @@
if (positiveResult) {
setEnabled(false);
- Context context = getContext();
- if (BrowserSettings.PREF_CLEAR_CACHE.equals(getKey())) {
- BrowserSettings.getInstance().clearCache(context);
- BrowserSettings.getInstance().clearDatabases(context);
- } else if (BrowserSettings.PREF_CLEAR_COOKIES.equals(getKey())) {
- BrowserSettings.getInstance().clearCookies(context);
- } else if (BrowserSettings.PREF_CLEAR_HISTORY.equals(getKey())) {
- BrowserSettings.getInstance().clearHistory(context);
- } else if (BrowserSettings.PREF_CLEAR_FORM_DATA.equals(getKey())) {
- BrowserSettings.getInstance().clearFormData(context);
- } else if (BrowserSettings.PREF_CLEAR_PASSWORDS.equals(getKey())) {
- BrowserSettings.getInstance().clearPasswords(context);
- } else if (BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS.equals(
+ BrowserSettings settings = BrowserSettings.getInstance();
+ if (PreferenceKeys.PREF_PRIVACY_CLEAR_CACHE.equals(getKey())) {
+ settings.clearCache();
+ settings.clearDatabases();
+ } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_COOKIES.equals(getKey())) {
+ settings.clearCookies();
+ } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(getKey())) {
+ settings.clearHistory();
+ } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_FORM_DATA.equals(getKey())) {
+ settings.clearFormData();
+ } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_PASSWORDS.equals(getKey())) {
+ settings.clearPasswords();
+ } else if (PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES.equals(
getKey())) {
- BrowserSettings.getInstance().resetDefaultPreferences(context);
+ settings.resetDefaultPreferences();
setEnabled(true);
- } else if (BrowserSettings.PREF_CLEAR_GEOLOCATION_ACCESS.equals(
+ } else if (PreferenceKeys.PREF_PRIVACY_CLEAR_GEOLOCATION_ACCESS.equals(
getKey())) {
- BrowserSettings.getInstance().clearLocationAccess(context);
+ settings.clearLocationAccess();
}
}
}
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index febf75b..1fdc260 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -204,27 +204,11 @@
mUiController.onUrlSelected(BrowserBookmarksPage.getUrl(c), false);
return true;
}
-
- @Override
- public void onFolderChanged(int level, Uri uri) {
- final int toggleFlags = ActionBar.DISPLAY_SHOW_CUSTOM
- | ActionBar.DISPLAY_HOME_AS_UP;
- // 1 is "bookmarks" root folder
- if (level <= 1) {
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- mActionBar.setDisplayOptions(0, toggleFlags);
- } else {
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- mActionBar.setDisplayOptions(toggleFlags, toggleFlags);
- }
- }
};
private void initFragments(Bundle extras) {
mBookmarks = BrowserBookmarksPage.newInstance(mBookmarkCallbackWrapper,
extras, mBookmarksHeader);
- mBookmarks.setBreadCrumbMaxVisible(2);
- mBookmarks.setBreadCrumbUseBackButton(false);
mHistory = BrowserHistoryPage.newInstance(mUiController, extras);
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index dcb62a6..6a951c2 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -16,11 +16,6 @@
package com.android.browser;
-import com.android.browser.IntentHandler.UrlData;
-import com.android.browser.UI.DropdownChangeListener;
-import com.android.browser.search.SearchEngine;
-import com.android.common.Search;
-
import android.app.Activity;
import android.app.DownloadManager;
import android.app.SearchManager;
@@ -56,7 +51,6 @@
import android.provider.ContactsContract;
import android.provider.ContactsContract.Intents.Insert;
import android.speech.RecognizerIntent;
-import android.speech.RecognizerResultsIntent;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
@@ -80,8 +74,17 @@
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
+
+import com.android.browser.IntentHandler.UrlData;
+import com.android.browser.UI.DropdownChangeListener;
+import com.android.browser.provider.BrowserProvider;
+import com.android.browser.search.SearchEngine;
+import com.android.common.Search;
+
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.HashMap;
@@ -96,6 +99,7 @@
private static final String LOGTAG = "Controller";
private static final String SEND_APP_ID_EXTRA =
"android.speech.extras.SEND_APPLICATION_ID_EXTRA";
+ private static final String INCOGNITO_URI = "browser:incognito";
// public message ids
@@ -132,6 +136,9 @@
// "source" parameter for Google search through simplily type
final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
+ // "no-crash-recovery" parameter in intetnt to suppress crash recovery
+ final static String NO_CRASH_RECOVERY = "no-crash-recovery";
+
private Activity mActivity;
private UI mUi;
private TabControl mTabControl;
@@ -197,6 +204,7 @@
// Tabs' notion of whether they represent bookmarked sites.
private ContentObserver mBookmarksObserver;
private DataController mDataController;
+ private CrashRecoveryHandler mCrashRecoveryHandler;
private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
@Override
@@ -218,7 +226,7 @@
mDataController = DataController.getInstance(mActivity);
mTabControl = new TabControl(this);
mSettings.setController(this);
- mSettings.updateRlzValues(mActivity);
+ mCrashRecoveryHandler = new CrashRecoveryHandler(this);
mUrlHandler = new UrlHandler(this);
mIntentHandler = new IntentHandler(mActivity, this);
@@ -252,6 +260,16 @@
}
void start(final Bundle icicle, final Intent intent) {
+ boolean noCrashRecovery = intent.getBooleanExtra(NO_CRASH_RECOVERY, false);
+ if (icicle != null || noCrashRecovery) {
+ mCrashRecoveryHandler.clearState();
+ doStart(icicle, intent);
+ } else {
+ mCrashRecoveryHandler.startRecovery(intent);
+ }
+ }
+
+ void doStart(final Bundle icicle, final Intent intent) {
// Unless the last browser usage was within 24 hours, destroy any
// remaining incognito tabs.
@@ -266,10 +284,10 @@
|| lastActiveDate.after(today));
// Find out if we will restore any state and remember the tab.
- final int currentTab =
+ final long currentTabId =
mTabControl.canRestoreState(icicle, restoreIncognitoTabs);
- if (currentTab == -1) {
+ if (currentTabId == -1) {
// Not able to restore so we go ahead and clear session cookies. We
// must do this before trying to login the user as we don't want to
// clear any session cookies set during login.
@@ -279,31 +297,29 @@
GoogleAccountLogin.startLoginIfNeeded(mActivity,
new Runnable() {
@Override public void run() {
- start(icicle, intent, currentTab, restoreIncognitoTabs);
+ onPreloginFinished(icicle, intent, currentTabId, restoreIncognitoTabs);
}
});
}
- private void start(Bundle icicle, Intent intent, int currentTab,
+ private void onPreloginFinished(Bundle icicle, Intent intent, long currentTabId,
boolean restoreIncognitoTabs) {
- if (currentTab == -1) {
+ if (currentTabId == -1) {
final Bundle extra = intent.getExtras();
// Create an initial tab.
// 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.
UrlData urlData = mIntentHandler.getUrlDataFromIntent(intent);
-
- String action = intent.getAction();
- final Tab t = mTabControl.createNewTab(
- (Intent.ACTION_VIEW.equals(action) &&
- intent.getData() != null)
- || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
- .equals(action),
- intent.getStringExtra(Browser.EXTRA_APPLICATION_ID),
- urlData.mUrl, false);
- addTab(t);
- setActiveTab(t);
+ Tab t = null;
+ if (urlData.isEmpty()) {
+ t = openTabToHomePage();
+ } else {
+ t = openTab(urlData);
+ }
+ if (t != null) {
+ t.setAppId(intent.getStringExtra(Browser.EXTRA_APPLICATION_ID));
+ }
WebView webView = t.getWebView();
if (extra != null) {
int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
@@ -311,17 +327,8 @@
webView.setInitialScale(scale);
}
}
-
- if (urlData.isEmpty()) {
- loadUrl(webView, mSettings.getHomePage());
- } else {
- // monkey protection against delayed start
- if (t != null) {
- loadUrlDataIn(t, urlData);
- }
- }
} else {
- mTabControl.restoreState(icicle, currentTab, restoreIncognitoTabs,
+ mTabControl.restoreState(icicle, currentTabId, restoreIncognitoTabs,
mUi.needsRestoreAllTabs());
mUi.updateTabs(mTabControl.getTabs());
// TabControl.restoreState() will create a new tab even if
@@ -334,7 +341,7 @@
new ClearThumbnails().execute(mTabControl.getThumbnailDir()
.listFiles());
// Read JavaScript flags if it exists.
- String jsFlags = getSettings().getJsFlags();
+ String jsFlags = getSettings().getJsEngineFlags();
if (jsFlags.trim().length() != 0) {
getCurrentWebView().setJsFlags(jsFlags);
}
@@ -475,10 +482,8 @@
break;
case R.id.open_newtab_context_menu_id:
final Tab parent = mTabControl.getCurrentTab();
- final Tab newTab = openTab(parent, url, false);
- if (newTab != null && newTab != parent) {
- parent.addChildTab(newTab);
- }
+ openTab(url, parent,
+ !mSettings.openInBackground(), true);
break;
case R.id.copy_link_context_menu_id:
copy(url);
@@ -610,9 +615,10 @@
mNetworkHandler.onPause();
WebView.disablePlatformNotifications();
+ mCrashRecoveryHandler.clearState();
}
- void onSaveInstanceState(Bundle outState) {
+ void onSaveInstanceState(Bundle outState, boolean saveImages) {
// the default implementation requires each view to have an id. As the
// browser handles the state itself and it doesn't use id for the views,
// don't call the default implementation. Otherwise it will trigger the
@@ -620,7 +626,7 @@
// focused view XXX has no id".
// Save all the tabs
- mTabControl.saveState(outState);
+ mTabControl.saveState(outState, saveImages);
// Save time so that we know how old incognito tabs (if any) are.
outState.putSerializable("lastActiveDate", Calendar.getInstance());
}
@@ -911,6 +917,11 @@
}
mDataController.updateVisitedHistory(url);
WebIconDatabase.getInstance().retainIconForPageUrl(url);
+ if (!mActivityPaused) {
+ // Since we clear the state in onPause, don't backup the current
+ // state if we are already paused
+ mCrashRecoveryHandler.backupState();
+ }
}
@Override
@@ -1056,22 +1067,28 @@
mActivity.startActivity(intent);
}
- public void activateVoiceSearchMode(String title) {
- mUi.showVoiceTitleBar(title);
+ @Override
+ public void activateVoiceSearchMode(String title, List<String> results) {
+ mUi.showVoiceTitleBar(title, results);
}
public void revertVoiceSearchMode(Tab tab) {
mUi.revertVoiceTitleBar(tab);
}
- public void showCustomView(Tab tab, View view,
+ public boolean supportsVoiceSearch() {
+ SearchEngine searchEngine = getSettings().getSearchEngine();
+ return (searchEngine != null && searchEngine.supportsVoiceSearch());
+ }
+
+ public void showCustomView(Tab tab, View view, int requestedOrientation,
WebChromeClient.CustomViewCallback callback) {
if (tab.inForeground()) {
if (mUi.isCustomViewShowing()) {
callback.onCustomViewHidden();
return;
}
- mUi.showCustomView(view, callback);
+ mUi.showCustomView(view, requestedOrientation, callback);
// Save the menu state and set it to empty while the custom
// view is showing.
mOldMenuState = mMenuState;
@@ -1098,7 +1115,7 @@
case PREFERENCES_PAGE:
if (resultCode == Activity.RESULT_OK && intent != null) {
String action = intent.getStringExtra(Intent.EXTRA_TEXT);
- if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
+ if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(action)) {
mTabControl.removeParentChildRelationShips();
}
}
@@ -1161,7 +1178,11 @@
removeComboView();
if (!TextUtils.isEmpty(url)) {
if (newTab) {
- openTab(mTabControl.getCurrentTab(), url, false);
+ final Tab parent = mTabControl.getCurrentTab();
+ openTab(url,
+ (parent != null) && parent.isPrivateBrowsingEnabled(),
+ !mSettings.openInBackground(),
+ true);
} else {
final Tab currentTab = mTabControl.getCurrentTab();
dismissSubWindow(currentTab);
@@ -1216,6 +1237,10 @@
}
}
+ protected boolean onMenuKey() {
+ return mUi.onMenuKey();
+ }
+
// menu handling and state
// TODO: maybe put into separate handler
@@ -1335,8 +1360,7 @@
boolean showNewTab = mTabControl.canCreateNewTab();
MenuItem newTabItem
= menu.findItem(R.id.open_newtab_context_menu_id);
- newTabItem.setTitle(
- BrowserSettings.getInstance().openInBackground()
+ newTabItem.setTitle(getSettings().openInBackground()
? R.string.contextmenu_openlink_newwindow_background
: R.string.contextmenu_openlink_newwindow);
newTabItem.setVisible(showNewTab);
@@ -1363,11 +1387,9 @@
@Override
public boolean onMenuItemClick(MenuItem item) {
final Tab parent = mTabControl.getCurrentTab();
- final Tab newTab = openTab(parent,
- extra, false);
- if (newTab != parent) {
- parent.addChildTab(newTab);
- }
+ openTab(extra, parent,
+ !mSettings.openInBackground(),
+ true);
return true;
}
});
@@ -1465,15 +1487,16 @@
PackageManager.MATCH_DEFAULT_ONLY);
menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
- boolean isNavDump = mSettings.isNavDump();
+ boolean isNavDump = mSettings.enableNavDump();
final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
nav.setVisible(isNavDump);
nav.setEnabled(isNavDump);
- boolean showDebugSettings = mSettings.showDebugSettings();
+ boolean showDebugSettings = mSettings.isDebugEnabled();
final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
counter.setVisible(showDebugSettings);
counter.setEnabled(showDebugSettings);
+ menu.findItem(R.id.freeze_tab_menu_id).setVisible(showDebugSettings);
final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
newtab.setEnabled(getTabControl().canCreateNewTab());
@@ -1580,6 +1603,26 @@
getCurrentTopWebView().showFindDialog(null, true);
break;
+ case R.id.freeze_tab_menu_id:
+ // TODO: Show error messages
+ WebView source = getCurrentTopWebView();
+ if (source == null) break;
+ Tab t = createNewTab(false, true, false);
+ if (t == null) break;
+ WebView pinned = t.getWebView();
+ if (pinned == null) break;
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ source.saveViewState(bos);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ pinned.loadViewState(bis);
+ bis.close();
+ bos.close();
+ } catch (IOException e) {
+ closeTab(t);
+ }
+ break;
+
case R.id.save_webarchive_menu_id:
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
@@ -1683,7 +1726,7 @@
Tab desiredTab = mTabControl.getTab(id);
if (desiredTab != null &&
desiredTab != mTabControl.getCurrentTab()) {
- switchToTab(id);
+ switchToTab(desiredTab);
}
break;
}
@@ -1774,7 +1817,6 @@
// title bar once again.
mExtendedMenuOpen = false;
mUi.onExtendedMenuClosed(mInLoad);
- mUi.onOptionsMenuOpened();
}
}
} else {
@@ -2103,7 +2145,8 @@
mTabControl.removeTab(tab);
}
- protected void setActiveTab(Tab tab) {
+ @Override
+ public void setActiveTab(Tab tab) {
// monkey protection against delayed start
if (tab != null) {
mTabControl.setCurrentTab(tab);
@@ -2116,9 +2159,9 @@
Tab current = mTabControl.getCurrentTab();
if (current != null
&& current.getWebView().copyBackForwardList().getSize() == 0) {
- Tab parent = current.getParentTab();
+ Tab parent = current.getParent();
if (parent != null) {
- switchToTab(mTabControl.getTabIndex(parent));
+ switchToTab(parent);
closeTab(current);
}
}
@@ -2135,7 +2178,7 @@
// TODO: analyze why the remove and add are necessary
mUi.attachTab(appTab);
if (mTabControl.getCurrentTab() != appTab) {
- switchToTab(mTabControl.getTabIndex(appTab));
+ switchToTab(appTab);
loadUrlDataIn(appTab, urlData);
} else {
// If the tab was the current tab, we have to attach
@@ -2169,92 +2212,89 @@
}
}
+ // open a non inconito tab with the given url data
+ // and set as active tab
+ public Tab openTab(UrlData urlData) {
+ Tab tab = createNewTab(false, true, true);
+ if ((tab != null) && !urlData.isEmpty()) {
+ loadUrlDataIn(tab, urlData);
+ }
+ return tab;
+ }
+
@Override
public Tab openTabToHomePage() {
- // check for max tabs
- if (mTabControl.canCreateNewTab()) {
- return openTabAndShow(null, new UrlData(mSettings.getHomePage()),
- false, null);
- } else {
- mUi.showMaxTabsWarning();
- return null;
- }
- }
-
- protected Tab openTab(Tab parent, String url, boolean forceForeground) {
- if (mSettings.openInBackground() && !forceForeground) {
- Tab tab = mTabControl.createNewTab(false, null, null,
- (parent != null) && parent.isPrivateBrowsingEnabled());
- if (tab != null) {
- addTab(tab);
- WebView view = tab.getWebView();
- loadUrl(view, url);
- }
- return tab;
- } else {
- return openTabAndShow(parent, new UrlData(url), false, null);
- }
- }
-
-
- // This method does a ton of stuff. It will attempt to create a new tab
- // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
- // url isn't null, it will load the given url.
- public Tab openTabAndShow(Tab parent, final UrlData urlData,
- boolean closeOnExit, String appId) {
- final Tab currentTab = mTabControl.getCurrentTab();
- if (mTabControl.canCreateNewTab()) {
- final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
- urlData.mUrl,
- (parent != null) && parent.isPrivateBrowsingEnabled());
- WebView webview = tab.getWebView();
- // We must set the new tab as the current tab to reflect the old
- // animation behavior.
- addTab(tab);
- setActiveTab(tab);
- if (!urlData.isEmpty()) {
- loadUrlDataIn(tab, urlData);
- }
- return tab;
- } else {
- // Get rid of the subwindow if it exists
- dismissSubWindow(currentTab);
- if (!urlData.isEmpty()) {
- // Load the given url.
- loadUrlDataIn(currentTab, urlData);
- }
- return currentTab;
- }
+ return openTab(mSettings.getHomePage(), false, true, false);
}
@Override
public Tab openIncognitoTab() {
- if (mTabControl.canCreateNewTab()) {
- Tab currentTab = mTabControl.getCurrentTab();
- Tab tab = mTabControl.createNewTab(false, null,
- null, true);
- addTab(tab);
- setActiveTab(tab);
- loadUrlDataIn(tab, new UrlData("browser:incognito"));
- return tab;
- } else {
- mUi.showMaxTabsWarning();
- return null;
+ return openTab(INCOGNITO_URI, true, true, false);
+ }
+
+ @Override
+ public Tab openTab(String url, boolean incognito, boolean setActive,
+ boolean useCurrent) {
+ return openTab(url, incognito, setActive, useCurrent, null);
+ }
+
+ @Override
+ public Tab openTab(String url, Tab parent, boolean setActive,
+ boolean useCurrent) {
+ return openTab(url, (parent != null) && parent.isPrivateBrowsingEnabled(),
+ setActive, useCurrent, parent);
+ }
+
+ public Tab openTab(String url, boolean incognito, boolean setActive,
+ boolean useCurrent, Tab parent) {
+ Tab tab = createNewTab(incognito, setActive, useCurrent);
+ if (tab != null) {
+ if (parent != null && parent != tab) {
+ parent.addChildTab(tab);
+ }
+ WebView w = tab.getWebView();
+ if (url != null) {
+ loadUrl(w, url);
+ }
}
+ return tab;
+ }
+
+ // this method will attempt to create a new tab
+ // incognito: private browsing tab
+ // setActive: ste tab as current tab
+ // useCurrent: if no new tab can be created, return current tab
+ private Tab createNewTab(boolean incognito, boolean setActive,
+ boolean useCurrent) {
+ Tab tab = null;
+ if (mTabControl.canCreateNewTab()) {
+ tab = mTabControl.createNewTab(incognito);
+ addTab(tab);
+ if (setActive) {
+ setActiveTab(tab);
+ }
+ } else {
+ if (useCurrent) {
+ tab = mTabControl.getCurrentTab();
+ // Get rid of the subwindow if it exists
+ dismissSubWindow(tab);
+ } else {
+ mUi.showMaxTabsWarning();
+ }
+ }
+ return tab;
}
/**
- * @param index Index of the tab to change to, as defined by
- * mTabControl.getTabIndex(Tab t).
+ * @param tab the tab to switch to
* @return boolean True if we successfully switched to a different tab. If
* the indexth tab is null, or if that tab is the same as
* the current one, return false.
*/
@Override
- public boolean switchToTab(int index) {
+ public boolean switchToTab(Tab tab) {
// hide combo view if open
removeComboView();
- Tab tab = mTabControl.getTab(index);
Tab currentTab = mTabControl.getCurrentTab();
if (tab == null || tab == currentTab) {
return false;
@@ -2267,25 +2307,20 @@
public void closeCurrentTab() {
// hide combo view if open
removeComboView();
- final Tab current = mTabControl.getCurrentTab();
if (mTabControl.getTabCount() == 1) {
mActivity.finish();
return;
}
- final Tab parent = current.getParentTab();
- int indexToShow = -1;
- if (parent != null) {
- indexToShow = mTabControl.getTabIndex(parent);
- } else {
- final int currentIndex = mTabControl.getCurrentIndex();
- // Try to move to the tab to the right
- indexToShow = currentIndex + 1;
- if (indexToShow > mTabControl.getTabCount() - 1) {
- // Try to move to the tab to the left
- indexToShow = currentIndex - 1;
+ final Tab current = mTabControl.getCurrentTab();
+ final int pos = mTabControl.getCurrentPosition();
+ Tab newTab = current.getParent();
+ if (newTab == null) {
+ newTab = mTabControl.getTab(pos + 1);
+ if (newTab == null) {
+ newTab = mTabControl.getTab(pos - 1);
}
}
- if (switchToTab(indexToShow)) {
+ if (switchToTab(newTab)) {
// Close window
closeTab(current);
}
@@ -2299,10 +2334,6 @@
public void closeTab(Tab tab) {
// hide combo view if open
removeComboView();
- int currentIndex = mTabControl.getCurrentIndex();
- int removeIndex = mTabControl.getTabIndex(tab);
- Tab newtab = mTabControl.getTab(currentIndex);
- setActiveTab(newtab);
removeTab(tab);
}
@@ -2370,18 +2401,12 @@
} else {
// Check to see if we are closing a window that was created by
// another window. If so, we switch back to that window.
- Tab parent = current.getParentTab();
+ Tab parent = current.getParent();
if (parent != null) {
- switchToTab(mTabControl.getTabIndex(parent));
+ switchToTab(parent);
// Now we close the other tab
closeTab(current);
} else {
- if (current.closeOnExit()) {
- // This will finish the activity if there is only one tab
- // open or it will switch to the next available tab if
- // available.
- closeCurrentTab();
- }
/*
* Instead of finishing the activity, simply push this to the back
* of the stack and let ActivityManager to choose the foreground
@@ -2414,12 +2439,6 @@
startSearch(result, false, bundle, false);
}
- @Override
- public void startSearch(String url) {
- startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
- null, false);
- }
-
private void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
if (appSearchData == null) {
@@ -2441,21 +2460,22 @@
return bundle;
}
- /**
+ /**
* helper method for key handler
* returns the current tab if it can't advance
*/
- private int getNextTabIndex() {
- return Math.min(mTabControl.getTabCount() - 1,
- mTabControl.getCurrentIndex() + 1);
+ private Tab getNextTab() {
+ return mTabControl.getTab(Math.min(mTabControl.getTabCount() - 1,
+ mTabControl.getCurrentPosition() + 1));
}
/**
* helper method for key handler
* returns the current tab if it can't advance
*/
- private int getPrevTabIndex() {
- return Math.max(0, mTabControl.getCurrentIndex() - 1);
+ private Tab getPrevTab() {
+ return mTabControl.getTab(Math.max(0,
+ mTabControl.getCurrentPosition() - 1));
}
/**
@@ -2467,9 +2487,16 @@
*/
boolean onKeyDown(int keyCode, KeyEvent event) {
boolean noModifiers = event.hasNoModifiers();
-
// Even if MENU is already held down, we need to call to super to open
// the IME on long press.
+ if (KeyEvent.KEYCODE_MENU == keyCode) {
+ if (mOptionsMenuHandler != null) {
+ return false;
+ } else {
+ event.startTracking();
+ return true;
+ }
+ }
if (!noModifiers
&& ((KeyEvent.KEYCODE_MENU == keyCode)
|| (KeyEvent.KEYCODE_CTRL_LEFT == keyCode)
@@ -2489,10 +2516,10 @@
if (event.isCtrlPressed()) {
if (event.isShiftPressed()) {
// prev tab
- switchToTab(getPrevTabIndex());
+ switchToTab(getPrevTab());
} else {
// next tab
- switchToTab(getNextTabIndex());
+ switchToTab(getNextTab());
}
return true;
}
@@ -2593,11 +2620,14 @@
}
boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (KeyEvent.KEYCODE_MENU == keyCode) {
+ mMenuIsDown = false;
+ if (event.isTracking() && !event.isCanceled()) {
+ return onMenuKey();
+ }
+ }
if (!event.hasNoModifiers()) return false;
switch(keyCode) {
- case KeyEvent.KEYCODE_MENU:
- mMenuIsDown = false;
- break;
case KeyEvent.KEYCODE_BACK:
if (event.isTracking() && !event.isCanceled()) {
onBackKey();
diff --git a/src/com/android/browser/CrashRecoveryHandler.java b/src/com/android/browser/CrashRecoveryHandler.java
new file mode 100644
index 0000000..60e39da
--- /dev/null
+++ b/src/com/android/browser/CrashRecoveryHandler.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2011 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.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+
+public class CrashRecoveryHandler {
+
+ private static final String LOGTAG = "BrowserCrashRecovery";
+ private static final String STATE_FILE = "browser_state.parcel";
+ private static final int BUFFER_SIZE = 4096;
+
+ private Controller mController;
+
+ public CrashRecoveryHandler(Controller controller) {
+ mController = controller;
+ }
+
+ public void backupState() {
+ final Bundle state = new Bundle();
+ mController.onSaveInstanceState(state, false);
+ final Context context = mController.getActivity();
+ new Thread() {
+ @Override
+ public void run() {
+ Parcel p = Parcel.obtain();
+ try {
+ state.writeToParcel(p, 0);
+ FileOutputStream fout = context.openFileOutput(STATE_FILE,
+ Context.MODE_PRIVATE);
+ fout.write(p.marshall());
+ fout.close();
+ } catch (Throwable e) {
+ Log.i(LOGTAG, "Failed to save persistent state", e);
+ } finally {
+ p.recycle();
+ }
+ }
+ }.start();
+ }
+
+ public void clearState() {
+ Context context = mController.getActivity();
+ context.deleteFile(STATE_FILE);
+ }
+
+ public void promptToRecover(final Bundle state, final Intent intent) {
+ new AlertDialog.Builder(mController.getActivity())
+ .setTitle(R.string.recover_title)
+ .setMessage(R.string.recover_prompt)
+ .setPositiveButton(R.string.recover_yes, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mController.doStart(state, intent);
+ }
+ })
+ .setNegativeButton(R.string.recover_no, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ clearState();
+ mController.doStart(null, intent);
+ }
+ })
+ .show();
+ }
+
+ public void startRecovery(Intent intent) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ Context context = mController.getActivity();
+ FileInputStream fin = context.openFileInput(STATE_FILE);
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int read;
+ while ((read = fin.read(buffer)) > 0) {
+ dataStream.write(buffer, 0, read);
+ }
+ byte[] data = dataStream.toByteArray();
+ parcel.unmarshall(data, 0, data.length);
+ parcel.setDataPosition(0);
+ Bundle state = parcel.readBundle();
+ promptToRecover(state, intent);
+ } catch (FileNotFoundException e) {
+ // No state to recover
+ mController.doStart(null, intent);
+ } catch (Exception e) {
+ Log.w(LOGTAG, "Failed to recover state!", e);
+ mController.doStart(null, intent);
+ } finally {
+ parcel.recycle();
+ }
+ }
+}
diff --git a/src/com/android/browser/InstantSearchEngine.java b/src/com/android/browser/InstantSearchEngine.java
index 85e494a..e2e9c8a 100644
--- a/src/com/android/browser/InstantSearchEngine.java
+++ b/src/com/android/browser/InstantSearchEngine.java
@@ -18,6 +18,7 @@
import com.android.browser.Controller;
import com.android.browser.R;
import com.android.browser.UI.DropdownChangeListener;
+import com.android.browser.provider.BrowserProvider;
import com.android.browser.search.SearchEngine;
import android.app.SearchManager;
@@ -174,7 +175,12 @@
* visible tab.
*/
private void switchSearchboxIfNeeded() {
- final SearchBox searchBox = getCurrentWebview().getSearchBox();
+ final WebView current = getCurrentWebview();
+ if (current == null) {
+ return;
+ }
+
+ final SearchBox searchBox = current.getSearchBox();
if (searchBox != mSearchBox) {
if (mSearchBox != null) {
mSearchBox.removeSearchBoxListener(mListener);
@@ -188,7 +194,12 @@
}
private boolean isInstantPage() {
- String currentUrl = getCurrentWebview().getUrl();
+ final WebView current = getCurrentWebview();
+ if (current == null) {
+ return false;
+ }
+
+ final String currentUrl = current.getUrl();
if (currentUrl != null) {
Uri uri = Uri.parse(currentUrl);
@@ -210,7 +221,10 @@
mController.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
- getCurrentWebview().loadUrl(getInstantBaseUrl());
+ final WebView current = getCurrentWebview();
+ if (current != null) {
+ current.loadUrl(getInstantBaseUrl());
+ }
}
});
}
@@ -292,7 +306,12 @@
}
private int rescaleHeight(int height) {
- final float scale = getCurrentWebview().getScale();
+ final WebView current = getCurrentWebview();
+ if (current == null) {
+ return 0;
+ }
+
+ final float scale = current.getScale();
if (scale != 0) {
return (int) (height / scale);
}
@@ -306,8 +325,10 @@
if (rescaledHeight != mHeight) {
mHeight = rescaledHeight;
- mSearchBox.setDimensions(0, 0, 0, rescaledHeight);
- mSearchBox.onresize();
+ if (mSearchBox != null) {
+ mSearchBox.setDimensions(0, 0, 0, rescaledHeight);
+ mSearchBox.onresize();
+ }
}
}
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index b556638..8d1b784 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -134,7 +134,7 @@
}
if (intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false)) {
- mController.openTabAndShow(mTabControl.getCurrentTab(), urlData, false, null);
+ mController.openTab(urlData);
return;
}
final String appId = intent
@@ -146,12 +146,15 @@
&& !mActivity.getPackageName().equals(appId)
&& (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
if (activateVoiceSearch) {
- Tab appTab = mTabControl.getTabFromId(appId);
+ Tab appTab = mTabControl.getTabFromAppId(appId);
if (appTab != null) {
mController.reuseTab(appTab, appId, urlData);
return;
} else {
- mController.openTabAndShow(null, urlData, false, appId);
+ Tab tab = mController.openTab(urlData);
+ if (tab != null) {
+ tab.setAppId(appId);
+ }
}
} else {
// No matching application tab, try to find a regular tab
@@ -159,7 +162,7 @@
Tab appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
if (appTab != null) {
if (current != appTab) {
- mController.switchToTab(mTabControl.getTabIndex(appTab));
+ mController.switchToTab(appTab);
}
// Otherwise, we are already viewing the correct tab.
} else {
@@ -168,7 +171,10 @@
// 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.
- mController.openTabAndShow(null, urlData, false, appId);
+ Tab tab = mController.openTab(urlData);
+ if (tab != null) {
+ tab.setAppId(appId);
+ }
}
}
} else {
@@ -187,7 +193,7 @@
} else if ("about:debug.nav".equals(urlData.mUrl)) {
current.getWebView().debugDump();
} else {
- mSettings.toggleDebugSettings(mActivity);
+ mSettings.toggleDebugSettings();
}
return;
}
@@ -221,17 +227,6 @@
headers.put(key, pairs.getString(key));
}
}
-
- // AppId will be set to the Browser for Search Bar initiated searches
- final String appId = intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
- if (mActivity.getPackageName().equals(appId)) {
- String rlz = mSettings.getRlzValue();
- Uri uri = Uri.parse(url);
- if (!rlz.isEmpty() && needsRlz(uri)) {
- Uri rlzUri = addRlzParameter(uri, rlz);
- url = rlzUri.toString();
- }
- }
}
} else if (Intent.ACTION_SEARCH.equals(action)
|| MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
@@ -375,19 +370,4 @@
}
}
- private static boolean needsRlz(Uri uri) {
- if ((uri.getQueryParameter("rlz") == null) &&
- (uri.getQueryParameter("q") != null) &&
- UrlUtils.isGoogleUri(uri)) {
- return true;
- }
- return false;
- }
-
- private static Uri addRlzParameter(Uri uri, String rlz) {
- if (rlz.isEmpty()) {
- return uri;
- }
- return uri.buildUpon().appendQueryParameter("rlz", rlz).build();
- }
}
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
new file mode 100644
index 0000000..6ef759f
--- /dev/null
+++ b/src/com/android/browser/NavScreen.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Configuration;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.Gallery;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ListPopupWindow;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NavScreen extends RelativeLayout implements OnClickListener {
+
+ UiController mUiController;
+ PhoneUi mUi;
+ Tab mTab;
+ Activity mActivity;
+
+ ImageButton mRefresh;
+ ImageButton mForward;
+ ImageButton mBookmarks;
+ ImageButton mMore;
+ ImageButton mNewTab;
+ ImageButton mNewIncognito;
+ FrameLayout mHolder;
+
+ TextView mTitle;
+ ImageView mFavicon;
+ ImageButton mCloseTab;
+
+ NavTabScroller mScroller;
+ float mTabAspect = 0.66f;
+ int mTabWidth;
+ int mTabHeight;
+ TabAdapter mAdapter;
+ ListPopupWindow mPopup;
+ int mOrientation;
+
+ public NavScreen(Activity activity, UiController ctl, PhoneUi ui) {
+ super(activity);
+ mActivity = activity;
+ mUiController = ctl;
+ mUi = ui;
+ mOrientation = activity.getResources().getConfiguration().orientation;
+ init();
+ }
+
+ protected Tab getSelectedTab() {
+ return (Tab) mScroller.getSelectedItem();
+ }
+
+ protected void showMenu() {
+ Menu menu = mUi.getMenu();
+ menu.setGroupVisible(R.id.NAV_MENU, false);
+
+ MenuAdapter menuAdapter = new MenuAdapter(mContext);
+ menuAdapter.setMenu(menu);
+ ListPopupWindow popup = new ListPopupWindow(mContext);
+ popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
+ popup.setAdapter(menuAdapter);
+ popup.setModal(true);
+ popup.setAnchorView(mMore);
+ popup.setWidth((int) mContext.getResources().getDimension(
+ R.dimen.menu_width));
+ popup.show();
+ mPopup = popup;
+ }
+
+ protected float getToolbarHeight() {
+ return mActivity.getResources().getDimension(R.dimen.toolbar_height);
+ }
+
+ protected void dismissMenu() {
+ if (mPopup != null) {
+ mPopup.dismiss();
+ }
+ }
+
+ // for configuration changes
+ @Override
+ protected void onConfigurationChanged(Configuration newconfig) {
+ if (newconfig.orientation != mOrientation) {
+ int selIx = mScroller.getSelectionIndex();
+ removeAllViews();
+ init();
+ mScroller.setSelection(selIx);
+ mOrientation = newconfig.orientation;
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ private void init() {
+ LayoutInflater.from(mContext).inflate(R.layout.nav_screen, this);
+ mBookmarks = (ImageButton) findViewById(R.id.bookmarks);
+ mNewTab = (ImageButton) findViewById(R.id.newtab);
+ mNewIncognito = (ImageButton) findViewById(R.id.newincognito);
+ mMore = (ImageButton) findViewById(R.id.more);
+ mBookmarks.setOnClickListener(this);
+ mNewTab.setOnClickListener(this);
+ mNewIncognito.setOnClickListener(this);
+ mMore.setOnClickListener(this);
+ mScroller = (NavTabScroller) findViewById(R.id.scroller);
+ mAdapter = new TabAdapter(mContext, mUiController.getTabControl());
+ mScroller.setAdapter(mAdapter);
+
+ // update state for active tab
+ mScroller.setSelection(mUiController.getTabControl().getTabPosition(mUi.getActiveTab()));
+ }
+
+ @Override
+ public void onClick(View v) {
+ WebView web = (mTab != null) ? mTab.getWebView() : null;
+ if (web != null) {
+ if (mForward == v) {
+ mUi.hideNavScreen(true);
+ web.goForward();
+ } else if (mRefresh == v) {
+ mUi.hideNavScreen(true);
+ web.reload();
+ }
+ }
+ if (mBookmarks == v) {
+ mUi.hideNavScreen(false);
+ switchToSelected();
+ mUiController.bookmarksOrHistoryPicker(false);
+ } else if (mNewTab == v) {
+ openNewTab();
+ } else if (mMore == v) {
+ showMenu();
+ } else if (mNewIncognito == v) {
+ mUi.hideNavScreen(true);
+ mUiController.openIncognitoTab();
+ } else if (mTitle == v) {
+ mUi.getTitleBar().setSkipTitleBarAnimations(true);
+ close(false);
+ mUi.editUrl(false);
+ mUi.getTitleBar().setSkipTitleBarAnimations(false);
+ }
+ }
+
+ private void onCloseTab(Tab tab) {
+ if (tab != null) {
+ mUiController.closeTab(tab);
+ if (mUiController.getTabControl().getTabCount() == 0) {
+ openNewTab();
+ } else {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+
+
+ private void openNewTab() {
+ // need to call openTab explicitely with setactive false
+ Tab tab = mUiController.openTab(BrowserSettings.getInstance().getHomePage(),
+ false, false, false);
+ mAdapter.notifyDataSetChanged();
+ if (tab != null) {
+ // set tab as the selected in flipper, then hide
+ final int tix = mUi.mTabControl.getTabPosition(tab);
+ mScroller.setSelection(tix);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mUi.hideNavScreen(true);
+ switchToSelected();
+ }
+ }, 100);
+ }
+ }
+
+ private void switchToSelected() {
+ Tab tab = (Tab) mScroller.getSelectedItem();
+ if (tab != mUi.getActiveTab()) {
+ mUiController.setActiveTab(tab);
+ }
+ }
+
+ protected void close() {
+ close(true);
+ }
+
+ protected void close(boolean animate) {
+ mUi.hideNavScreen(animate);
+ }
+
+ class TabGallery extends Gallery {
+
+ public TabGallery(Context ctx) {
+ super(ctx);
+ setUnselectedAlpha(0.3f);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new Gallery.LayoutParams(mTabWidth, mTabHeight);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
+ return generateDefaultLayoutParams();
+ }
+
+ }
+
+ class TabAdapter extends BaseAdapter {
+
+ Context context;
+ TabControl tabControl;
+
+ public TabAdapter(Context ctx, TabControl tc) {
+ context = ctx;
+ tabControl = tc;
+ }
+
+ @Override
+ public int getCount() {
+ return tabControl.getTabCount();
+ }
+
+ @Override
+ public Tab getItem(int position) {
+ return tabControl.getTab(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ final NavTabView tabview = new NavTabView(mActivity);
+ final Tab tab = getItem(position);
+ final BrowserWebView web = (BrowserWebView) tab.getWebView();
+ tabview.setWebView(mUi, tab);
+ tabview.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (tabview.isRefresh(v)) {
+ mUi.hideNavScreen(true);
+ web.reload();
+ } else if (tabview.isClose(v)) {
+ onCloseTab((Tab) (mScroller.getSelectedItem()));
+ } else if (tabview.isTitle(v)) {
+ mUi.getTitleBar().setSkipTitleBarAnimations(true);
+ close(false);
+ mUi.editUrl(false);
+ mUi.getTitleBar().setSkipTitleBarAnimations(false);
+ } else if (tabview.isForward(v)) {
+ mUi.hideNavScreen(true);
+ web.goForward();
+ } else if (tabview.isWebView(v)) {
+ mScroller.setSelection(position);
+ close();
+
+ }
+ }
+ });
+ return tabview;
+ }
+
+ }
+
+ private class MenuAdapter extends BaseAdapter implements OnClickListener {
+
+ List<MenuItem> mItems;
+ LayoutInflater mInflater;
+
+ public MenuAdapter(Context ctx) {
+ mInflater = LayoutInflater.from(ctx);
+ mItems = new ArrayList<MenuItem>();
+ }
+
+ public void setMenu(Menu menu) {
+ mItems.clear();
+ for (int i = 0; i < menu.size(); i++) {
+ MenuItem item = menu.getItem(i);
+ if (item.isEnabled() && item.isVisible()) {
+ mItems.add(item);
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public MenuItem getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getTag() != null) {
+ dismissMenu();
+ mActivity.closeOptionsMenu();
+ mUi.hideNavScreen(false);
+ mUiController.onOptionsItemSelected((MenuItem) v.getTag());
+ }
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final MenuItem item = mItems.get(position);
+ View view = mInflater.inflate(R.layout.qc_menu_item, null);
+ TextView label = (TextView) view.findViewById(R.id.title);
+ label.setText(item.getTitle());
+ label.setTag(item);
+ label.setOnClickListener(this);
+ return label;
+ }
+
+ }
+
+
+}
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
new file mode 100644
index 0000000..bd26df7
--- /dev/null
+++ b/src/com/android/browser/NavTabScroller.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2011 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.content.Context;
+import android.content.res.Configuration;
+import android.database.DataSetObserver;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import com.android.browser.view.HorizontalScrollView;
+import com.android.browser.view.ScrollView;
+
+/**
+ * custom view for displaying tabs in the nav screen
+ */
+public class NavTabScroller extends FrameLayout {
+
+ private LinearLayout mContentView;
+ private BaseAdapter mAdapter;
+ private SelectableSroller mScroller;
+ private int mOrientation;
+
+ public NavTabScroller(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public NavTabScroller(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public NavTabScroller(Context context) {
+ super(context);
+ init(context);
+ }
+
+ private void init(Context ctx) {
+ mOrientation = ctx.getResources().getConfiguration().orientation;
+ mScroller = (mOrientation == Configuration.ORIENTATION_LANDSCAPE) ?
+ new HorizontalScroller(ctx) : new VerticalScroller(ctx);
+ mContentView = mScroller.getContentView();
+ View sview = (View) mScroller;
+ sview.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ addView(sview);
+ }
+
+ @Override
+ protected void onMeasure(int wspec, int hspec) {
+ super.onMeasure(wspec, hspec);
+ calcPadding();
+ }
+
+ private void calcPadding() {
+ if (mAdapter.getCount() > 0) {
+ View v = mContentView.getChildAt(0);
+ if (mOrientation == Configuration.ORIENTATION_PORTRAIT) {
+ int pad = (getMeasuredHeight() - v.getMeasuredHeight()) / 2;
+ mContentView.setPadding(0, pad, 0, pad);
+ } else {
+ int pad = (getMeasuredWidth() - v.getMeasuredWidth()) / 2;
+ mContentView.setPadding(pad, 0, pad, 0);
+ }
+ }
+ }
+
+ protected void setAdapter(BaseAdapter adapter) {
+ mAdapter = adapter;
+ mAdapter.registerDataSetObserver(new DataSetObserver() {
+
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ populateList();
+ }
+
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ }
+ });
+ populateList();
+ }
+
+ protected void setSelection(int ix) {
+ mScroller.setSelection(ix);
+ }
+
+ protected int getSelectionIndex() {
+ return mScroller.getSelection();
+ }
+
+ protected Tab getSelectedItem() {
+ return (Tab) mAdapter.getItem(mScroller.getSelection());
+ }
+
+ protected ViewGroup getContentView() {
+ return mContentView;
+ }
+
+ private void populateList() {
+ mContentView.removeAllViewsInLayout();
+ for (int i = 0; i < mAdapter.getCount(); i++) {
+ NavTabView v = (NavTabView) mAdapter.getView(i, null, mContentView);
+ mContentView.addView(v);
+ }
+ }
+
+ View getSelectedTab() {
+ int selected = mScroller.getSelection();
+ if ((selected >= 0) && (selected < mContentView.getChildCount())) {
+ return mContentView.getChildAt(selected);
+ } else {
+ return null;
+ }
+ }
+
+ static interface SelectableSroller {
+ void setSelection(int index);
+ int getSelection();
+ LinearLayout getContentView();
+
+ }
+
+ static class VerticalScroller extends ScrollView implements SelectableSroller {
+
+ private LinearLayout mContentView;
+ private int mSelected;
+ private boolean mSnapScroll;
+
+ public VerticalScroller(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public VerticalScroller(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public VerticalScroller(Context context) {
+ super(context);
+ init(context);
+ }
+
+ private void init(Context ctx) {
+ setHorizontalScrollBarEnabled(false);
+ mContentView = new LinearLayout(ctx);
+ mContentView.setOrientation(LinearLayout.VERTICAL);
+ setVerticalScrollBarEnabled(false);
+ setSmoothScrollingEnabled(true);
+ mContentView.setLayoutParams(
+ new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ addView(mContentView);
+
+ }
+
+ public LinearLayout getContentView() {
+ return mContentView;
+ }
+
+ public void setSelection(int ix) {
+ mSelected = ix;
+ }
+
+ public int getSelection() {
+ return mSelected;
+ }
+
+ protected void onScrollChanged(int sl, int st, int ol, int ot) {
+ int midy = getScrollY() + getHeight() / 2;
+ int sel = -1;
+ for (int i = 0; i < mContentView.getChildCount(); i++) {
+ NavTabView child = (NavTabView) mContentView.getChildAt(i);
+ int top = child.getTop();
+ int bottom = child.getBottom();
+ if (top <= midy && bottom >= midy) {
+ sel = i;
+ } else {
+ // check if on screen
+ if (top > getScrollY() + getHeight() || bottom < getScrollY()) {
+ if (!child.isPaused()) {
+ child.pause();
+ }
+ } else {
+ if (child.isPaused()) {
+ child.resume();
+ }
+ }
+ }
+ }
+ if (sel != -1) {
+ if (sel != mSelected) {
+ setSelection(sel);
+ }
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent evt) {
+ // save drag state before super call
+ boolean dragged = mIsBeingDragged;
+ boolean result = super.onTouchEvent(evt);
+ if (MotionEvent.ACTION_UP == evt.getActionMasked()) {
+ if (mScroller.isFinished() && dragged) {
+ snapToSelected();
+ }
+ } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
+ NavTabView ntv = (NavTabView) getSelectedView();
+ if (mIsBeingDragged && ntv.isHighlighted()) {
+ ntv.setHighlighted(false);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void computeScroll() {
+ super.computeScroll();
+ if (mScroller.isFinished() && !mIsBeingDragged) {
+ if (!mSnapScroll) {
+ snapToSelected();
+ } else {
+ // reset snap scrolling flag
+ mSnapScroll = false;
+ NavTabView ntv = (NavTabView) getSelectedView();
+ ntv.setHighlighted(true);
+ }
+ }
+ }
+
+ private void snapToSelected() {
+ View v = mContentView.getChildAt(mSelected);
+ int top = (v.getTop() + v.getBottom()) / 2;
+ top -= getHeight() / 2;
+ if (top != getScrollY()) {
+ // snap to selected
+ mSnapScroll = true;
+ smoothScrollTo(0, top);
+ } else {
+ NavTabView ntv = (NavTabView) getSelectedView();
+ ntv.setHighlighted(true);
+ }
+ }
+
+ protected View getSelectedView() {
+ return mContentView.getChildAt(mSelected);
+ }
+
+ }
+
+ static class HorizontalScroller extends HorizontalScrollView implements SelectableSroller {
+
+ private LinearLayout mContentView;
+ private int mSelected;
+ private boolean mSnapScroll;
+
+ public HorizontalScroller(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public HorizontalScroller(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public HorizontalScroller(Context context) {
+ super(context);
+ init(context);
+ }
+
+ private void init(Context ctx) {
+ setHorizontalScrollBarEnabled(false);
+ mContentView = new LinearLayout(ctx);
+ mContentView.setOrientation(LinearLayout.HORIZONTAL);
+ setVerticalScrollBarEnabled(false);
+ setSmoothScrollingEnabled(true);
+ mContentView.setLayoutParams(
+ new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
+ addView(mContentView);
+ }
+
+ public LinearLayout getContentView() {
+ return mContentView;
+ }
+
+ public void setSelection(int ix) {
+ mSelected = ix;
+ }
+
+ public int getSelection() {
+ return mSelected;
+ }
+
+ protected void onScrollChanged(int sl, int st, int ol, int ot) {
+ int midx = getScrollX() + getWidth() / 2;
+ int sel = -1;
+ for (int i = 0; i < mContentView.getChildCount(); i++) {
+ View child = mContentView.getChildAt(i);
+ if (child.getLeft() <= midx && child.getRight() >= midx) {
+ sel = i;
+ break;
+ }
+ }
+ if (sel != -1) {
+ if (sel != mSelected) {
+ setSelection(sel);
+ }
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent evt) {
+ // save drag state before super call
+ boolean dragged = mIsBeingDragged;
+ boolean result = super.onTouchEvent(evt);
+ if (MotionEvent.ACTION_UP == evt.getActionMasked()) {
+ if (mScroller.isFinished() && dragged) {
+ snapToSelected();
+ }
+ } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
+ NavTabView ntv = (NavTabView) getSelectedView();
+ if (mIsBeingDragged && ntv.isHighlighted()) {
+ ntv.setHighlighted(false);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void computeScroll() {
+ super.computeScroll();
+ if (mScroller.isFinished() && !mIsBeingDragged) {
+ if (!mSnapScroll) {
+ snapToSelected();
+ } else {
+ // reset snap scrolling flag
+ mSnapScroll = false;
+ NavTabView ntv = (NavTabView) getSelectedView();
+ ntv.setHighlighted(true);
+ }
+ }
+ }
+
+ private void snapToSelected() {
+ View v = mContentView.getChildAt(mSelected);
+ int left = (v.getLeft() + v.getRight()) / 2;
+ left -= getWidth() / 2;
+ if (left != getScrollX()) {
+ // snap to selected
+ mSnapScroll = true;
+ smoothScrollTo(left, 0);
+ } else {
+ NavTabView ntv = (NavTabView) getSelectedView();
+ ntv.setHighlighted(true);
+ }
+ }
+
+ protected View getSelectedView() {
+ return mContentView.getChildAt(mSelected);
+ }
+
+ }
+
+}
diff --git a/src/com/android/browser/NavTabView.java b/src/com/android/browser/NavTabView.java
new file mode 100644
index 0000000..061e024
--- /dev/null
+++ b/src/com/android/browser/NavTabView.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2011 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.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class NavTabView extends LinearLayout {
+
+ private Tab mTab;
+ private BrowserWebView mWebView;
+ private WebProxyView mProxy;
+ private ImageButton mForward;
+ private ImageButton mRefresh;
+ private ImageView mFavicon;
+ private ImageButton mClose;
+ private FrameLayout mContainer;
+ private TextView mTitle;
+ private View mTitleBar;
+ private OnClickListener mClickListener;
+ private boolean mHighlighted;
+ private Drawable mTitleBg;
+ private Drawable mUrlBg;
+ private float mMediumTextSize;
+ private float mSmallTextSize;
+ private boolean mPaused;
+
+ public NavTabView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ public NavTabView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public NavTabView(Context context) {
+ super(context);
+ init();
+ }
+
+ private void init() {
+ final Resources res = mContext.getResources();
+ mMediumTextSize = res.getDimension(R.dimen.nav_tab_text_normal);
+ mSmallTextSize = res.getDimension(R.dimen.nav_tab_text_small);
+ LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view,
+ this);
+ mContainer = (FrameLayout) findViewById(R.id.tab_view);
+ mForward = (ImageButton) findViewById(R.id.forward);
+ mClose = (ImageButton) findViewById(R.id.closetab);
+ mRefresh = (ImageButton) findViewById(R.id.refresh);
+ mTitle = (TextView) findViewById(R.id.title);
+ mFavicon = (ImageView) findViewById(R.id.favicon);
+ mTitleBar = findViewById(R.id.titlebar);
+ mTitleBg = res.getDrawable(R.drawable.bg_urlbar);
+ mUrlBg = res.getDrawable(
+ com.android.internal.R.drawable.edit_text_holo_dark);
+ setState(false);
+ }
+
+ protected void pause() {
+ mPaused = true;
+ mWebView.onPause();
+ }
+
+ protected void resume() {
+ mPaused = false;
+ mWebView.onResume();
+ }
+
+ protected boolean isPaused() {
+ return mPaused;
+ }
+
+ protected boolean isRefresh(View v) {
+ return v == mRefresh;
+ }
+
+ protected boolean isClose(View v) {
+ return v == mClose;
+ }
+
+ protected boolean isTitle(View v) {
+ return v == mTitleBar;
+ }
+
+ protected boolean isForward(View v) {
+ return v == mForward;
+ }
+
+ protected boolean isWebView(View v) {
+ return v == mProxy;
+ }
+
+ protected void setHighlighted(boolean highlighted) {
+ if (highlighted == mHighlighted) return;
+ mHighlighted = highlighted;
+ setState(highlighted);
+ }
+
+ private void setState(boolean highlighted) {
+ if (highlighted) {
+ setAlpha(1.0f);
+ mRefresh.setVisibility(View.VISIBLE);
+ mFavicon.setVisibility(View.VISIBLE);
+ mForward.setVisibility(mWebView.canGoForward()
+ ? View.VISIBLE : View.GONE);
+ mTitleBar.setBackgroundDrawable(mTitleBg);
+ mClose.setVisibility(View.VISIBLE);
+ mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMediumTextSize);
+ mTitle.setBackgroundDrawable(mUrlBg);
+ } else {
+ setAlpha(0.8f);
+ mForward.setVisibility(View.GONE);
+ mRefresh.setVisibility(View.INVISIBLE);
+ mFavicon.setVisibility(View.INVISIBLE);
+ mClose.setVisibility(View.GONE);
+ mTitleBar.setBackgroundDrawable(null);
+ mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mSmallTextSize);
+ mTitle.setBackgroundDrawable(null);
+ }
+ setTitle();
+ }
+
+ private void setTitle() {
+ if (mTab == null) return;
+ if (mHighlighted) {
+ mTitle.setText(mTab.getUrl());
+ } else {
+ String txt = mTab.getTitle();
+ if (txt == null) txt = mTab.getUrl();
+ mTitle.setText(txt);
+ }
+ }
+
+ protected boolean isHighlighted() {
+ return mHighlighted;
+ }
+
+ protected void setWebView(PhoneUi ui, Tab tab) {
+ mTab = tab;
+ BrowserWebView web = (BrowserWebView) tab.getWebView();
+ if (web == null) return;
+ mWebView = web;
+ removeFromParent(mWebView);
+ mProxy = new WebProxyView(mContext, mWebView);
+ mContainer.addView(mProxy, 0);
+ if (mWebView != null) {
+ mForward.setVisibility(mWebView.canGoForward()
+ ? View.VISIBLE : View.GONE);
+ }
+ mFavicon.setImageDrawable(ui.getFaviconDrawable(tab.getFavicon()));
+ setTitle();
+ }
+
+ protected void hideTitle() {
+ mTitleBar.setVisibility(View.INVISIBLE);
+ }
+
+ @Override
+ public void setOnClickListener(OnClickListener listener) {
+ mClickListener = listener;
+ mTitleBar.setOnClickListener(mClickListener);
+ mRefresh.setOnClickListener(mClickListener);
+ mForward.setOnClickListener(mClickListener);
+ mClose.setOnClickListener(mClickListener);
+ if (mProxy != null) {
+ mProxy.setOnClickListener(mClickListener);
+ }
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ mWebView.setProxyView(null);
+ }
+
+ private static void removeFromParent(View v) {
+ if (v.getParent() != null) {
+ ((ViewGroup) v.getParent()).removeView(v);
+ }
+ }
+
+ static class WebProxyView extends View {
+
+ private BrowserWebView mWeb;
+
+ public WebProxyView(Context context, BrowserWebView web) {
+ super(context);
+ setWillNotDraw(false);
+ mWeb = web;
+ mWeb.setProxyView(this);
+
+ }
+
+ public void onDraw(Canvas c) {
+ c.translate(-mWeb.getScrollX(), -mWeb.getScrollY());
+ mWeb.onDraw(c);
+ }
+
+ }
+
+}
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index f1939e4..f94a8ab 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -17,17 +17,15 @@
package com.android.browser;
import android.app.Activity;
-import android.content.Context;
-import android.graphics.PixelFormat;
+import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowManager;
import android.webkit.WebView;
+import android.widget.FrameLayout;
/**
* Ui for regular phone screen sizes
@@ -35,13 +33,17 @@
public class PhoneUi extends BaseUi {
private static final String LOGTAG = "PhoneUi";
+ private static final float NAV_TAB_SCALE = 0.75f;
- private TitleBar mTitleBar;
+ private TitleBarPhone mTitleBar;
private ActiveTabsPage mActiveTabsPage;
- private TouchProxy mTitleOverlay;
+ private boolean mUseQuickControls;
+ private PieControl mPieControl;
+ private NavScreen mNavScreen;
boolean mExtendedMenuOpen;
boolean mOptionsMenuOpen;
+ boolean mAnimating;
/**
* @param browser
@@ -49,11 +51,13 @@
*/
public PhoneUi(Activity browser, UiController controller) {
super(browser, controller);
- mTitleBar = new TitleBar(mActivity, mUiController, this);
+ mTitleBar = new TitleBarPhone(mActivity, mUiController, this,
+ mContentView);
// mTitleBar will be always be shown in the fully loaded mode on
// phone
mTitleBar.setProgress(100);
mActivity.getActionBar().hide();
+ setUseQuickControls(BrowserSettings.getInstance().useQuickControls());
}
@Override
@@ -62,23 +66,6 @@
mActivity.getActionBar().hide();
}
- // webview factory
-
- @Override
- public WebView createWebView(boolean privateBrowsing) {
- // Create a new WebView
- WebView w = new WebView(mActivity, null,
- android.R.attr.webViewStyle, privateBrowsing);
- initWebViewSettings(w);
- return w;
- }
-
- @Override
- public WebView createSubWebView(boolean privateBrowsing) {
- WebView web = createWebView(privateBrowsing);
- return web;
- }
-
// lifecycle
@Override
@@ -100,8 +87,10 @@
@Override
public void editUrl(boolean clearInput) {
- String url = getActiveTab().getUrl();
- mUiController.startSearch(url);
+ if (mUseQuickControls) {
+ getTitleBar().setShowProgressOnly(false);
+ }
+ super.editUrl(clearInput);
}
@Override
@@ -110,11 +99,35 @@
// if tab page is showing, hide it
mUiController.removeActiveTabsPage(true);
return true;
+ } else if (mNavScreen != null) {
+ mNavScreen.close();
+ return true;
}
return super.onBackKey();
}
@Override
+ public boolean onMenuKey() {
+ if (!isComboViewShowing()) {
+ if (mNavScreen == null) {
+ showNavScreen();
+ } else {
+ mNavScreen.close();
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean dispatchKey(int code, KeyEvent event) {
+ if (!isComboViewShowing()) {
+ }
+ return false;
+ }
+
+ @Override
public void onProgressChanged(Tab tab) {
if (tab.inForeground()) {
int progress = tab.getLoadProgress();
@@ -122,9 +135,16 @@
if (progress == 100) {
if (!mOptionsMenuOpen || !mExtendedMenuOpen) {
hideTitleBar();
+ if (mUseQuickControls) {
+ mTitleBar.setShowProgressOnly(false);
+ }
}
} else {
if (!mOptionsMenuOpen || mExtendedMenuOpen) {
+ if (mUseQuickControls && !mTitleBar.isEditingUrl()) {
+ mTitleBar.setShowProgressOnly(true);
+ setTitleGravity(Gravity.TOP);
+ }
showTitleBar();
}
}
@@ -132,41 +152,41 @@
}
@Override
- public void setActiveTab(Tab tab) {
- super.setActiveTab(tab);
- WebView view = tab.getWebView();
+ public void setActiveTab(final Tab tab) {
+ captureTab(mActiveTab);
+ super.setActiveTab(tab, true);
+ setActiveTab(tab, true);
+ }
+
+ @Override
+ void setActiveTab(Tab tab, boolean needsAttaching) {
+ BrowserWebView view = (BrowserWebView) tab.getWebView();
// TabControl.setCurrentTab has been called before this,
// so the tab is guaranteed to have a webview
if (view == null) {
Log.e(LOGTAG, "active tab with no webview detected");
return;
}
- view.setEmbeddedTitleBar(getTitleBar());
+ // Request focus on the top window.
+ if (mUseQuickControls) {
+ mPieControl.forceToTop(mContentView);
+ view.setScrollListener(null);
+ } else {
+ // check if title bar is already attached by animation
+ if (mTitleBar.getParent() == null) {
+ view.setEmbeddedTitleBar(mTitleBar);
+ }
+ }
if (tab.isInVoiceSearchMode()) {
- showVoiceTitleBar(tab.getVoiceDisplayTitle());
+ showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults());
} else {
revertVoiceTitleBar(tab);
}
+ updateLockIconToLatest(tab);
tab.getTopWindow().requestFocus();
}
@Override
- protected void showTitleBar() {
- if (canShowTitleBar()) {
- setTitleGravity(Gravity.TOP);
- super.showTitleBar();
- }
- }
-
- @Override
- protected void hideTitleBar() {
- if (isTitleBarShowing()) {
- setTitleGravity(Gravity.NO_GRAVITY);
- super.hideTitleBar();
- }
- }
-
- @Override
protected TitleBarBase getTitleBar() {
return mTitleBar;
}
@@ -175,6 +195,7 @@
@Override
public void showActiveTabsPage() {
+ captureTab(mActiveTab);
mActiveTabsPage = new ActiveTabsPage(mActivity, mUiController);
mTitleBar.setVisibility(View.GONE);
hideTitleBar();
@@ -193,6 +214,14 @@
}
@Override
+ public void showComboView(boolean startWithHistory, Bundle extras) {
+ if (mNavScreen != null) {
+ hideNavScreen(false);
+ }
+ super.showComboView(startWithHistory, extras);
+ }
+
+ @Override
public boolean showsWeb() {
return super.showsWeb() && mActiveTabsPage == null;
}
@@ -200,42 +229,6 @@
// menu handling callbacks
@Override
- public void onOptionsMenuOpened() {
- mOptionsMenuOpen = true;
- // options menu opened, show title bar
- showTitleBar();
- if (mTitleOverlay == null) {
- // This assumes that getTitleBar always returns the same View
- mTitleOverlay = new TouchProxy(mActivity, getTitleBar());
- }
- mActivity.getWindowManager().addView(mTitleOverlay,
- mTitleOverlay.getWindowLayoutParams());
- }
-
- @Override
- public void onExtendedMenuOpened() {
- // Switching the menu to expanded view, so hide the
- // title bar.
- mExtendedMenuOpen = true;
- hideTitleBar();
- }
-
- @Override
- public void onOptionsMenuClosed(boolean inLoad) {
- mOptionsMenuOpen = false;
- mActivity.getWindowManager().removeView(mTitleOverlay);
- if (!inLoad && !getTitleBar().hasFocus()) {
- hideTitleBar();
- }
- }
-
- @Override
- public void onExtendedMenuClosed(boolean inLoad) {
- mExtendedMenuOpen = false;
- showTitleBar();
- }
-
- @Override
public void onContextMenuCreated(Menu menu) {
hideTitleBar();
}
@@ -255,36 +248,77 @@
}
@Override
- public boolean dispatchKey(int code, KeyEvent event) {
- return false;
+ public void onActionModeFinished(boolean inLoad) {
+ if (inLoad) {
+ if (mUseQuickControls) {
+ mTitleBar.setShowProgressOnly(true);
+ }
+ showTitleBar();
+ }
+ mActivity.getActionBar().hide();
}
- static class TouchProxy extends View {
-
- View mTarget;
-
- TouchProxy(Context context, View target) {
- super(context);
- mTarget = target;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- return mTarget.dispatchTouchEvent(event);
- }
-
- WindowManager.LayoutParams getWindowLayoutParams() {
- WindowManager.LayoutParams params =
- new WindowManager.LayoutParams(
- mTarget.getWidth(),
- mTarget.getHeight(),
- WindowManager.LayoutParams.TYPE_APPLICATION,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
- PixelFormat.TRANSPARENT);
- params.gravity = Gravity.TOP | Gravity.LEFT;
- params.y = mTarget.getTop();
- params.x = mTarget.getLeft();
- return params;
+ @Override
+ protected void setTitleGravity(int gravity) {
+ if (mUseQuickControls) {
+ FrameLayout.LayoutParams lp =
+ (FrameLayout.LayoutParams) getTitleBar().getLayoutParams();
+ lp.gravity = gravity;
+ getTitleBar().setLayoutParams(lp);
+ } else {
+ super.setTitleGravity(gravity);
}
}
+
+ private void setUseQuickControls(boolean useQuickControls) {
+ mUseQuickControls = useQuickControls;
+ getTitleBar().setUseQuickControls(mUseQuickControls);
+ if (useQuickControls) {
+ mPieControl = new PieControl(mActivity, mUiController, this);
+ mPieControl.attachToContainer(mContentView);
+ WebView web = getWebView();
+ if (web != null) {
+ web.setEmbeddedTitleBar(null);
+ }
+ } else {
+ if (mPieControl != null) {
+ mPieControl.removeFromContainer(mContentView);
+ }
+ WebView web = getWebView();
+ if (web != null) {
+ web.setEmbeddedTitleBar(mTitleBar);
+ }
+ setTitleGravity(Gravity.NO_GRAVITY);
+ }
+ }
+
+ @Override
+ protected void captureTab(final Tab tab) {
+ if (tab == null) return;
+ BrowserWebView web = (BrowserWebView) tab.getWebView();
+ if (web != null) {
+ tab.setScreenshot(web.capture());
+ }
+ }
+
+ void showNavScreen() {
+ detachTab(mActiveTab);
+ mNavScreen = new NavScreen(mActivity, mUiController, this);
+ // Add the custom view to its container.
+ mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
+ mContentView.setVisibility(View.GONE);
+ mCustomViewContainer.setVisibility(View.VISIBLE);
+ mCustomViewContainer.bringToFront();
+ }
+
+ void hideNavScreen(boolean animate) {
+ Tab tab = mNavScreen.getSelectedTab();
+ mCustomViewContainer.removeView(mNavScreen);
+ mNavScreen = null;
+ mCustomViewContainer.setVisibility(View.GONE);
+ mUiController.setActiveTab(tab);
+ // Show the content view.
+ mContentView.setVisibility(View.VISIBLE);
+ }
+
}
diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java
index 38ed1bb..8bcd972 100644
--- a/src/com/android/browser/PieControl.java
+++ b/src/com/android/browser/PieControl.java
@@ -50,7 +50,7 @@
private Activity mActivity;
private UiController mUiController;
- private XLargeUi mUi;
+ private BaseUi mUi;
private PieMenu mPie;
private PieItem mBack;
private PieItem mForward;
@@ -66,7 +66,7 @@
private TextView mTabsCount;
private int mItemSize;
- public PieControl(Activity activity, UiController controller, XLargeUi ui) {
+ public PieControl(Activity activity, UiController controller, BaseUi ui) {
mActivity = activity;
mUiController = controller;
mUi = ui;
@@ -107,7 +107,7 @@
menuview.setLayoutListener(new OnLayoutListener() {
@Override
public void onLayout(int ax, int ay, boolean left) {
- mActivity.openOptionsMenu();
+ buildMenu();
}
});
@@ -128,10 +128,10 @@
// level 2
mPie.addItem(mForward);
mPie.addItem(mRefresh);
+ mPie.addItem(mOptions);
mPie.addItem(mShowTabs);
mPie.addItem(mNewTab);
mPie.addItem(mClose);
- mPie.addItem(mOptions);
mPie.setController(this);
}
container.addView(mPie);
@@ -142,11 +142,13 @@
mUi.captureTab(mUi.getActiveTab());
mTabAdapter.setTabs(tabs);
PieStackView sym = (PieStackView) mShowTabs.getPieView();
- sym.setCurrent(mUiController.getTabControl().getCurrentIndex());
+ sym.setCurrent(mUiController.getTabControl().getCurrentPosition());
}
- protected void onMenuOpened(Menu menu) {
+ private void buildMenu() {
+ Menu menu = mUi.getMenu();
+ menu.setGroupVisible(R.id.NAV_MENU, false);
mMenuAdapter.setMenu(menu);
}
@@ -205,12 +207,12 @@
web.reload();
}
} else if (mUrl.getView() == v) {
- mUi.showTitleBarAndEdit();
+ mUi.editUrl(false);
} else if (mBookmarks.getView() == v) {
mUiController.bookmarksOrHistoryPicker(false);
} else if (mNewTab.getView() == v) {
mUiController.openTabToHomePage();
- mUi.showTitleBarAndEdit();
+ mUi.editUrl(false);
} else if (mClose.getView() == v) {
mUiController.closeCurrentTab();
}
@@ -279,8 +281,7 @@
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mUiController.switchToTab(mUiController.getTabControl()
- .getTabIndex(tab));
+ mUiController.switchToTab(tab);
}
});
return view;
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
new file mode 100644
index 0000000..cff9f70
--- /dev/null
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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;
+
+public interface PreferenceKeys {
+
+ static final String PREF_AUTOFILL_ACTIVE_PROFILE_ID = "autofill_active_profile_id";
+ static final String PREF_DEBUG_MENU = "debug_menu";
+
+ // ----------------------
+ // Keys for accessibility_preferences.xml
+ // ----------------------
+ static final String PREF_MIN_FONT_SIZE = "min_font_size";
+ static final String PREF_TEXT_SIZE = "text_size";
+ static final String PREF_FORCE_USERSCALABLE = "force_userscalable";
+
+ // ----------------------
+ // Keys for advanced_preferences.xml
+ // ----------------------
+ static final String PREF_AUTOFIT_PAGES = "autofit_pages";
+ static final String PREF_BLOCK_POPUP_WINDOWS = "block_popup_windows";
+ static final String PREF_DEFAULT_TEXT_ENCODING = "default_text_encoding";
+ static final String PREF_DEFAULT_ZOOM = "default_zoom";
+ static final String PREF_ENABLE_JAVASCRIPT = "enable_javascript";
+ static final String PREF_LOAD_IMAGES = "load_images";
+ static final String PREF_LOAD_PAGE = "load_page";
+ static final String PREF_OPEN_IN_BACKGROUND = "open_in_background";
+ static final String PREF_PLUGIN_STATE = "plugin_state";
+ static final String PREF_RESET_DEFAULT_PREFERENCES = "reset_default_preferences";
+ static final String PREF_SEARCH_ENGINE = "search_engine";
+ static final String PREF_WEBSITE_SETTINGS = "website_settings";
+
+ // ----------------------
+ // Keys for debug_preferences.xml
+ // ----------------------
+ static final String PREF_ENABLE_HARDWARE_ACCEL = "enable_hardware_accel";
+ static final String PREF_USER_AGENT = "user_agent";
+
+ // ----------------------
+ // Keys for general_preferences.xml
+ // ----------------------
+ static final String PREF_AUTOFILL_ENABLED = "autofill_enabled";
+ static final String PREF_AUTOFILL_PROFILE = "autofill_profile";
+ static final String PREF_HOMEPAGE = "homepage";
+ static final String PREF_SYNC_WITH_CHROME = "sync_with_chrome";
+
+ // ----------------------
+ // Keys for hidden_debug_preferences.xml
+ // ----------------------
+ static final String PREF_ENABLE_LIGHT_TOUCH = "enable_light_touch";
+ static final String PREF_ENABLE_NAV_DUMP = "enable_nav_dump";
+ static final String PREF_ENABLE_TRACING = "enable_tracing";
+ static final String PREF_ENABLE_VISUAL_INDICATOR = "enable_visual_indicator";
+ static final String PREF_JAVASCRIPT_CONSOLE = "javascript_console";
+ static final String PREF_JS_ENGINE_FLAGS = "js_engine_flags";
+ static final String PREF_NORMAL_LAYOUT = "normal_layout";
+ static final String PREF_SMALL_SCREEN = "small_screen";
+ static final String PREF_WIDE_VIEWPORT = "wide_viewport";
+
+ // ----------------------
+ // Keys for lab_preferences.xml
+ // ----------------------
+ static final String PREF_ENABLE_QUICK_CONTROLS = "enable_quick_controls";
+ static final String PREF_USE_MOST_VISITED_HOMEPAGE = "use_most_visited_homepage";
+ static final String PREF_USE_INSTANT_SEARCH = "use_instant_search";
+ static final String PREF_FULLSCREEN = "fullscreen";
+ static final String PREF_ENABLE_USERAGENT_SWITCHER = "enable_useragent_switcher";
+
+ // ----------------------
+ // Keys for privacy_security_preferences.xml
+ // ----------------------
+ static final String PREF_ACCEPT_COOKIES = "accept_cookies";
+ static final String PREF_ENABLE_GEOLOCATION = "enable_geolocation";
+ static final String PREF_PRIVACY_CLEAR_CACHE = "privacy_clear_cache";
+ static final String PREF_PRIVACY_CLEAR_COOKIES = "privacy_clear_cookies";
+ static final String PREF_PRIVACY_CLEAR_FORM_DATA = "privacy_clear_form_data";
+ static final String PREF_PRIVACY_CLEAR_GEOLOCATION_ACCESS = "privacy_clear_geolocation_access";
+ static final String PREF_PRIVACY_CLEAR_HISTORY = "privacy_clear_history";
+ static final String PREF_PRIVACY_CLEAR_PASSWORDS = "privacy_clear_passwords";
+ static final String PREF_REMEMBER_PASSWORDS = "remember_passwords";
+ static final String PREF_SAVE_FORMDATA = "save_formdata";
+ static final String PREF_SHOW_SECURITY_WARNINGS = "show_security_warnings";
+
+}
diff --git a/src/com/android/browser/RlzReceiver.java b/src/com/android/browser/RlzReceiver.java
deleted file mode 100644
index 1dfb11a..0000000
--- a/src/com/android/browser/RlzReceiver.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 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.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * This {@link BroadcastReceiver} handles RLZ broadcast notifications.
- */
-public class RlzReceiver extends BroadcastReceiver {
- public static final String RLZ_VALUES_UPDATED_ACTION =
- "android.intent.action.RLZ_VALUES_UPDATED";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (RLZ_VALUES_UPDATED_ACTION.equals(action)) {
- BrowserSettings settings = BrowserSettings.getInstance();
- settings.updateRlzValues(context);
- }
- }
-}
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 16a4cbe..af1788d 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -38,8 +38,6 @@
mBookmarks = (BrowserBookmarksPage) getFragmentManager()
.findFragmentById(R.id.bookmarks);
mBookmarks.setEnableContextMenu(false);
- mBookmarks.setBreadCrumbMaxVisible(2);
- mBookmarks.setBreadCrumbUseBackButton(true);
mBookmarks.setCallbackListener(this);
View cancel = findViewById(R.id.cancel);
if (cancel != null) {
@@ -73,10 +71,6 @@
}
@Override
- public void onFolderChanged(int level, Uri uri) {
- }
-
- @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cancel:
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index ecdaa15..242e170 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -71,6 +71,7 @@
final Object mResultsLock = new Object();
List<String> mVoiceResults;
boolean mIncognitoMode;
+ BrowserSettings mSettings;
interface CompletionListener {
@@ -82,6 +83,7 @@
public SuggestionsAdapter(Context ctx, CompletionListener listener) {
mContext = ctx;
+ mSettings = BrowserSettings.getInstance();
mListener = listener;
mLinesPortrait = mContext.getResources().
getInteger(R.integer.max_suggest_lines_portrait);
@@ -276,7 +278,7 @@
}
private boolean shouldProcessEmptyQuery() {
- final SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
+ final SearchEngine searchEngine = mSettings.getSearchEngine();
return searchEngine.wantsEmptyQuery();
}
@@ -470,7 +472,6 @@
Uri.Builder ub = BrowserContract.Combined.CONTENT_URI.buildUpon();
ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
Integer.toString(Math.max(mLinesLandscape, mLinesPortrait)));
- BookmarkUtils.addAccountInfo(mContext, ub);
mCursor =
mContext.getContentResolver().query(ub.build(), COMBINED_PROJECTION,
selection,
@@ -541,7 +542,7 @@
if (mCursor != null) {
mCursor.close();
}
- SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine();
+ SearchEngine searchEngine = mSettings.getSearchEngine();
if (!TextUtils.isEmpty(constraint)) {
if (searchEngine != null && searchEngine.supportsSuggestions()) {
mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
@@ -560,7 +561,7 @@
}
private boolean useInstant() {
- return BrowserSettings.getInstance().useInstant();
+ return mSettings.useInstantSearch();
}
public void clearCache() {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 863fc95..b0a991a 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -88,6 +88,9 @@
Activity mActivity;
private WebViewController mWebViewController;
+ // The tab ID
+ private long mId;
+
// The Geolocation permissions prompt
private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
// Main WebView wrapper
@@ -104,12 +107,10 @@
private Bundle mSavedState;
// Parent Tab. This is the Tab that created this Tab, or null if the Tab was
// created by the UI
- private Tab mParentTab;
+ private Tab mParent;
// Tab that constructed by this Tab. This is used when this Tab is
// destroyed, it clears all mParentTab values in the children.
- private Vector<Tab> mChildTabs;
- // If true, the tab will be removed when back out of the first page.
- private boolean mCloseOnExit;
+ private Vector<Tab> mChildren;
// If true, the tab is in the foreground of the current activity.
private boolean mInForeground;
// If true, the tab is in page loading state (after onPageStarted,
@@ -139,6 +140,7 @@
DownloadTouchIcon mTouchIconLoader;
private Bitmap mScreenshot;
+ private BrowserSettings mSettings;
// All the state needed for a page
private static class PageState {
@@ -182,20 +184,14 @@
private PageState mCurrentState;
// Used for saving and restoring each Tab
- // TODO: Figure out who uses what and where
- // Some of these aren't use in this class, and some are only used in
- // restoring state but not saving it - FIX THIS
- static final String WEBVIEW = "webview";
- static final String NUMTABS = "numTabs";
- static final String CURRTAB = "currentTab";
+ static final String ID = "ID";
static final String CURRURL = "currentUrl";
static final String CURRTITLE = "currentTitle";
- static final String CLOSEONEXIT = "closeonexit";
static final String PARENTTAB = "parentTab";
static final String APPID = "appid";
- static final String ORIGINALURL = "originalUrl";
static final String INCOGNITO = "privateBrowsingEnabled";
static final String SCREENSHOT = "screenshot";
+ static final String USERAGENT = "useragent";
// -------------------------------------------------------------------------
@@ -313,7 +309,9 @@
mVoiceSearchData.mLastVoiceSearchTitle
= mVoiceSearchData.mVoiceSearchResults.get(index);
if (mInForeground) {
- mWebViewController.activateVoiceSearchMode(mVoiceSearchData.mLastVoiceSearchTitle);
+ mWebViewController.activateVoiceSearchMode(
+ mVoiceSearchData.mLastVoiceSearchTitle,
+ mVoiceSearchData.mVoiceSearchResults);
}
if (mVoiceSearchData.mVoiceSearchHtmls != null) {
// When index was found it was already ensured that it was valid
@@ -709,7 +707,7 @@
setLockIconType(LockIcon.LOCK_ICON_UNSECURE);
return;
}
- if (BrowserSettings.getInstance().showSecurityWarnings()) {
+ if (mSettings.showSecurityWarnings()) {
final LayoutInflater factory =
LayoutInflater.from(mActivity);
final View warningsView =
@@ -856,12 +854,8 @@
mWebViewController.attachSubWindow(Tab.this);
transport.setWebView(mSubView);
} else {
- final Tab newTab = mWebViewController.openTabAndShow(
- Tab.this,
- IntentHandler.EMPTY_URL_DATA, false, null);
- if (newTab != Tab.this) {
- Tab.this.addChildTab(newTab);
- }
+ final Tab newTab = mWebViewController.openTab(null,
+ Tab.this, true, true);
transport.setWebView(newTab.getWebView());
}
msg.sendToTarget();
@@ -935,18 +929,16 @@
@Override
public void onRequestFocus(WebView view) {
if (!mInForeground) {
- mWebViewController.switchToTab(mWebViewController.getTabControl().getTabIndex(
- Tab.this));
+ mWebViewController.switchToTab(Tab.this);
}
}
@Override
public void onCloseWindow(WebView window) {
- if (mParentTab != null) {
+ if (mParent != null) {
// JavaScript can only close popup window.
if (mInForeground) {
- mWebViewController.switchToTab(mWebViewController.getTabControl()
- .getTabIndex(mParentTab));
+ mWebViewController.switchToTab(mParent);
}
mWebViewController.closeTab(Tab.this);
}
@@ -991,8 +983,14 @@
@Override
public void onShowCustomView(View view,
WebChromeClient.CustomViewCallback callback) {
+ onShowCustomView(view, mActivity.getRequestedOrientation(), callback);
+ }
+
+ @Override
+ public void onShowCustomView(View view, int requestedOrientation,
+ WebChromeClient.CustomViewCallback callback) {
if (mInForeground) mWebViewController.showCustomView(Tab.this, view,
- callback);
+ requestedOrientation, callback);
}
@Override
@@ -1015,7 +1013,7 @@
public void onExceededDatabaseQuota(String url,
String databaseIdentifier, long currentQuota, long estimatedSize,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
- BrowserSettings.getInstance().getWebStorageSizeManager()
+ mSettings.getWebStorageSizeManager()
.onExceededDatabaseQuota(url, databaseIdentifier,
currentQuota, estimatedSize, totalUsedQuota,
quotaUpdater);
@@ -1034,7 +1032,7 @@
@Override
public void onReachedMaxAppCacheSize(long spaceNeeded,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
- BrowserSettings.getInstance().getWebStorageSizeManager()
+ mSettings.getWebStorageSizeManager()
.onReachedMaxAppCacheSize(spaceNeeded, totalUsedQuota,
quotaUpdater);
}
@@ -1172,10 +1170,7 @@
if (disableAutoFill.isChecked()) {
// Disable autofill and show a toast with how to turn it on again.
- BrowserSettings s = BrowserSettings.getInstance();
- s.addObserver(mMainView.getSettings());
- s.disableAutoFill(mActivity);
- s.update();
+ mSettings.setAutofillEnabled(false);
Toast.makeText(mActivity,
R.string.autofill_setup_dialog_negative_toast,
Toast.LENGTH_LONG).show();
@@ -1290,14 +1285,13 @@
// remove later
// Construct a new tab
- Tab(WebViewController wvcontroller, WebView w, boolean closeOnExit, String appId,
- String url) {
+ Tab(WebViewController wvcontroller, WebView w) {
mWebViewController = wvcontroller;
mActivity = mWebViewController.getActivity();
- mCloseOnExit = closeOnExit;
- mAppId = appId;
+ mSettings = BrowserSettings.getInstance();
mDataController = DataController.getInstance(mActivity);
- mCurrentState = new PageState(mActivity, w.isPrivateBrowsingEnabled());
+ mCurrentState = new PageState(mActivity, w != null
+ ? w.isPrivateBrowsingEnabled() : false);
mInPageLoad = false;
mInForeground = false;
@@ -1328,6 +1322,14 @@
setWebView(w);
}
+ public void setId(long id) {
+ mId = id;
+ }
+
+ public long getId() {
+ return mId;
+ }
+
/**
* Sets the WebView for this tab, correctly removing the old WebView from
* the container view.
@@ -1366,7 +1368,6 @@
void destroy() {
if (mMainView != null) {
dismissSubWindow();
- BrowserSettings.getInstance().deleteObserver(mMainView.getSettings());
// save the WebView to call destroy() after detach it from the tab
WebView webView = mMainView;
setWebView(null);
@@ -1379,14 +1380,14 @@
*/
void removeFromTree() {
// detach the children
- if (mChildTabs != null) {
- for(Tab t : mChildTabs) {
- t.setParentTab(null);
+ if (mChildren != null) {
+ for(Tab t : mChildren) {
+ t.setParent(null);
}
}
// remove itself from the parent list
- if (mParentTab != null) {
- mParentTab.mChildTabs.remove(this);
+ if (mParent != null) {
+ mParent.mChildren.remove(this);
}
}
@@ -1428,8 +1429,6 @@
void dismissSubWindow() {
if (mSubView != null) {
mWebViewController.endActionMode();
- BrowserSettings.getInstance().deleteObserver(
- mSubView.getSettings());
mSubView.destroy();
mSubView = null;
mSubViewContainer = null;
@@ -1440,20 +1439,34 @@
/**
* Set the parent tab of this tab.
*/
- void setParentTab(Tab parent) {
- mParentTab = parent;
+ void setParent(Tab parent) {
+ mParent = parent;
// This tab may have been freed due to low memory. If that is the case,
- // the parent tab index is already saved. If we are changing that index
+ // the parent tab id is already saved. If we are changing that id
// (most likely due to removing the parent tab) we must update the
- // parent tab index in the saved Bundle.
+ // parent tab id in the saved Bundle.
if (mSavedState != null) {
if (parent == null) {
mSavedState.remove(PARENTTAB);
} else {
- mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl()
- .getTabIndex(parent));
+ mSavedState.putLong(PARENTTAB, parent.getId());
}
}
+
+ // Sync the WebView useragent with the parent
+ if (parent != null && mSettings.hasDesktopUseragent(parent.getWebView())
+ != mSettings.hasDesktopUseragent(getWebView())) {
+ mSettings.toggleDesktopUseragent(getWebView());
+ }
+ }
+
+ /**
+ * If this Tab was created through another Tab, then this method returns
+ * that Tab.
+ * @return the Tab parent or null
+ */
+ public Tab getParent() {
+ return mParent;
}
/**
@@ -1462,15 +1475,15 @@
* @param child the Tab that was created from this Tab
*/
void addChildTab(Tab child) {
- if (mChildTabs == null) {
- mChildTabs = new Vector<Tab>();
+ if (mChildren == null) {
+ mChildren = new Vector<Tab>();
}
- mChildTabs.add(child);
- child.setParentTab(this);
+ mChildren.add(child);
+ child.setParent(this);
}
- Vector<Tab> getChildTabs() {
- return mChildTabs;
+ Vector<Tab> getChildren() {
+ return mChildren;
}
void resume() {
@@ -1658,24 +1671,6 @@
return mErrorConsole;
}
- /**
- * If this Tab was created through another Tab, then this method returns
- * that Tab.
- * @return the Tab parent or null
- */
- public Tab getParentTab() {
- return mParentTab;
- }
-
- /**
- * Return whether this tab should be closed when it is backing out of the
- * first page.
- * @return TRUE if this tab should be closed when exit.
- */
- boolean closeOnExit() {
- return mCloseOnExit;
- }
-
private void setLockIconType(LockIcon icon) {
mCurrentState.mLockIcon = icon;
mWebViewController.onUpdatedLockIcon(this);
@@ -1717,6 +1712,15 @@
return mSavedState;
}
+ Bundle getSavedState(boolean saveImages) {
+ if (saveImages && mScreenshot != null) {
+ Bundle b = new Bundle(mSavedState);
+ b.putParcelable(SCREENSHOT, mScreenshot);
+ return b;
+ }
+ return mSavedState;
+ }
+
/**
* Set the saved state.
*/
@@ -1740,20 +1744,18 @@
// Store some extra info for displaying the tab in the picker.
final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
+ mSavedState.putLong(ID, mId);
mSavedState.putString(CURRURL, mCurrentState.mUrl);
mSavedState.putString(CURRTITLE, mCurrentState.mTitle);
- mSavedState.putBoolean(CLOSEONEXIT, mCloseOnExit);
if (mAppId != null) {
mSavedState.putString(APPID, mAppId);
}
// Remember the parent tab so the relationship can be restored.
- if (mParentTab != null) {
- mSavedState.putInt(PARENTTAB, mWebViewController.getTabControl().getTabIndex(
- mParentTab));
+ if (mParent != null) {
+ mSavedState.putLong(PARENTTAB, mParent.mId);
}
- if (mScreenshot != null) {
- mSavedState.putParcelable(SCREENSHOT, mScreenshot);
- }
+ mSavedState.putBoolean(USERAGENT,
+ mSettings.hasDesktopUseragent(getWebView()));
return true;
}
@@ -1767,9 +1769,13 @@
// Restore the internal state even if the WebView fails to restore.
// This will maintain the app id, original url and close-on-exit values.
mSavedState = null;
- mCloseOnExit = b.getBoolean(CLOSEONEXIT);
+ mId = b.getLong(ID);
mAppId = b.getString(APPID);
mScreenshot = b.getParcelable(SCREENSHOT);
+ if (b.getBoolean(USERAGENT)
+ != mSettings.hasDesktopUseragent(getWebView())) {
+ mSettings.toggleDesktopUseragent(getWebView());
+ }
final WebBackForwardList list = mMainView.restoreState(b);
if (list == null) {
diff --git a/src/com/android/browser/TabBar.java b/src/com/android/browser/TabBar.java
index 7abb203..6c3949a 100644
--- a/src/com/android/browser/TabBar.java
+++ b/src/com/android/browser/TabBar.java
@@ -16,7 +16,7 @@
package com.android.browser;
-import com.android.browser.ScrollWebView.ScrollListener;
+import com.android.browser.BrowserWebView.ScrollListener;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
@@ -166,7 +166,7 @@
TabView tv = buildTabView(tab);
mTabs.addTab(tv);
}
- mTabs.setSelectedTab(mTabControl.getCurrentIndex());
+ mTabs.setSelectedTab(mTabControl.getCurrentPosition());
}
@Override
@@ -213,7 +213,7 @@
mUi.hideTitleBar();
} else {
mUi.stopWebViewScrolling();
- mUi.showTitleBarAndEdit();
+ mUi.editUrl(false);
}
} else if (mUi.isTitleBarShowing() && !isLoading()) {
mUi.stopEditingUrl();
@@ -221,11 +221,12 @@
} else {
showUrlBar();
}
- } else {
+ } else if (view instanceof TabView) {
+ final Tab tab = ((TabView) view).mTab;
int ix = mTabs.getChildIndex(view);
if (ix >= 0) {
mTabs.setSelectedTab(ix);
- mUiController.switchToTab(ix);
+ mUiController.switchToTab(tab);
}
}
}
@@ -616,7 +617,7 @@
// TabChangeListener implementation
public void onSetActiveTab(Tab tab) {
- mTabs.setSelectedTab(mTabControl.getTabIndex(tab));
+ mTabs.setSelectedTab(mTabControl.getTabPosition(tab));
TabView tv = mTabMap.get(tab);
if (tv != null) {
tv.setProgress(tv.mTab.getLoadProgress());
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index af9928a..0aaf3d6 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -16,11 +16,8 @@
package com.android.browser;
-import com.android.browser.IntentHandler.UrlData;
-
import android.os.Bundle;
import android.util.Log;
-import android.webkit.WebBackForwardList;
import android.webkit.WebView;
import java.io.File;
@@ -32,6 +29,13 @@
class TabControl {
// Log Tag
private static final String LOGTAG = "TabControl";
+
+ // next Tab ID
+ private static long sNextId = 0;
+
+ private static final String POSITIONS = "positions";
+ private static final String CURRENT = "current";
+
// Maximum number of tabs.
private int mMaxTabs;
// Private array of WebViews that are used as tabs.
@@ -57,6 +61,10 @@
mTabQueue = new ArrayList<Tab>(mMaxTabs);
}
+ static long getNextId() {
+ return sNextId++;
+ }
+
File getThumbnailDir() {
return mThumbnailDir;
}
@@ -107,13 +115,13 @@
}
/**
- * Return the tab at the specified index.
- * @return The Tab for the specified index or null if the tab does not
+ * Return the tab at the specified position.
+ * @return The Tab for the specified position or null if the tab does not
* exist.
*/
- Tab getTab(int index) {
- if (index >= 0 && index < mTabs.size()) {
- return mTabs.get(index);
+ Tab getTab(int position) {
+ if (position >= 0 && position < mTabs.size()) {
+ return mTabs.get(position);
}
return null;
}
@@ -127,19 +135,19 @@
}
/**
- * Return the current tab index.
- * @return The current tab index
+ * Return the current tab position.
+ * @return The current tab position
*/
- int getCurrentIndex() {
+ int getCurrentPosition() {
return mCurrentTab;
}
/**
- * Given a Tab, find it's index
+ * Given a Tab, find it's position
* @param Tab to find
- * @return index of Tab or -1 if not found
+ * @return position of Tab or -1 if not found
*/
- int getTabIndex(Tab tab) {
+ int getTabPosition(Tab tab) {
if (tab == null) {
return -1;
}
@@ -156,7 +164,8 @@
*/
boolean hasAnyOpenIncognitoTabs() {
for (Tab tab : mTabs) {
- if (tab.getWebView() != null && tab.getWebView().isPrivateBrowsingEnabled()) {
+ if (tab.getWebView() != null
+ && tab.getWebView().isPrivateBrowsingEnabled()) {
return true;
}
}
@@ -168,8 +177,7 @@
* @return The newly createTab or null if we have reached the maximum
* number of open tabs.
*/
- Tab createNewTab(boolean closeOnExit, String appId, String url,
- boolean privateBrowsing) {
+ Tab createNewTab(boolean privateBrowsing) {
int size = mTabs.size();
// Return false if we have maxed out on tabs
if (mMaxTabs == size) {
@@ -178,7 +186,8 @@
final WebView w = createNewWebView(privateBrowsing);
// Create a new tab and add it to the tab list
- Tab t = new Tab(mController, w, closeOnExit, appId, url);
+ Tab t = new Tab(mController, w);
+ t.setId(getNextId());
mTabs.add(t);
// Initially put the tab in the background.
t.putInBackground();
@@ -190,7 +199,7 @@
* appId(null), url(null), and privateBrowsing(false).
*/
Tab createNewTab() {
- return createNewTab(false, null, null, false);
+ return createNewTab(false);
}
/**
@@ -225,7 +234,7 @@
} else {
// If a tab that is earlier in the list gets removed, the current
// index no longer points to the correct tab.
- mCurrentTab = getTabIndex(current);
+ mCurrentTab = getTabPosition(current);
}
// destroy the tab
@@ -233,17 +242,6 @@
// clear it's references to parent and children
t.removeFromTree();
- // The tab indices have shifted, update all the saved state so we point
- // to the correct index.
- for (Tab tab : mTabs) {
- Vector<Tab> children = tab.getChildTabs();
- if (children != null) {
- for (Tab child : children) {
- child.setParentTab(tab);
- }
- }
- }
-
// Remove it from the queue of viewed tabs.
mTabQueue.remove(t);
return true;
@@ -268,61 +266,61 @@
return mTabs.size();
}
-
/**
- * Save the state of all the Tabs.
- * @param outState The Bundle to save the state to.
+ * save the tab state:
+ * current position
+ * position sorted array of tab ids
+ * for each tab id, save the tab state
+ * @param outState
+ * @param saveImages
*/
- void saveState(Bundle outState) {
+ void saveState(Bundle outState, boolean saveImages) {
final int numTabs = getTabCount();
- outState.putInt(Tab.NUMTABS, numTabs);
- final int index = getCurrentIndex();
- outState.putInt(Tab.CURRTAB, (index >= 0 && index < numTabs) ? index : 0);
- for (int i = 0; i < numTabs; i++) {
- final Tab t = getTab(i);
- if (t.saveState()) {
- outState.putBundle(Tab.WEBVIEW + i, t.getSavedState());
+ long[] ids = new long[numTabs];
+ int i = 0;
+ for (Tab tab : mTabs) {
+ ids[i++] = tab.getId();
+ if (tab.saveState()) {
+ outState.putBundle(Long.toString(tab.getId()),
+ tab.getSavedState(saveImages));
}
}
+ outState.putLongArray(POSITIONS, ids);
+ final long cid = getCurrentTab().getId();
+ outState.putLong(CURRENT, cid);
}
/**
* Check if the state can be restored. If the state can be restored, the
- * current tab index is returned. This can be passed to restoreState below
+ * current tab id is returned. This can be passed to restoreState below
* in order to restore the correct tab. Otherwise, -1 is returned and the
* state cannot be restored.
*/
- int canRestoreState(Bundle inState, boolean restoreIncognitoTabs) {
- final int numTabs = (inState == null)
- ? - 1 : inState.getInt(Tab.NUMTABS, -1);
- if (numTabs == -1) {
+ long canRestoreState(Bundle inState, boolean restoreIncognitoTabs) {
+ final long[] ids = (inState == null) ? null : inState.getLongArray(POSITIONS);
+ if (ids == null) {
return -1;
}
- final int oldCurrentTab = inState.getInt(Tab.CURRTAB, -1);
-
- // Determine whether the saved current tab can be restored, and if not,
- // which tab will take its place.
- int currentTab = -1;
+ final long oldcurrent = inState.getLong(CURRENT);
+ long current = -1;
if (restoreIncognitoTabs ||
- !inState.getBundle(Tab.WEBVIEW + oldCurrentTab)
- .getBoolean(Tab.INCOGNITO)) {
- currentTab = oldCurrentTab;
+ !inState.getBundle(Long.toString(oldcurrent)).getBoolean(Tab.INCOGNITO)) {
+ current = oldcurrent;
} else {
- for (int i = 0; i < numTabs; i++) {
- if (!inState.getBundle(Tab.WEBVIEW + i)
- .getBoolean(Tab.INCOGNITO)) {
- currentTab = i;
+ // pick first non incognito tab
+ for (long id : ids) {
+ if (!inState.getBundle(Long.toString(id)).getBoolean(Tab.INCOGNITO)) {
+ current = id;
break;
}
}
}
-
- return currentTab;
+ return current;
}
/**
* Restore the state of all the tabs.
- * @param currentTab The tab index to restore.
+ * @param currentId The tab id to restore.
* @param inState The saved state of all the tabs.
* @param restoreIncognitoTabs Restoring private browsing tabs
* @param restoreAll All webviews get restored, not just the current tab
@@ -330,29 +328,29 @@
* @return True if there were previous tabs that were restored. False if
* there was no saved state or restoring the state failed.
*/
- void restoreState(Bundle inState, int currentTab,
+ void restoreState(Bundle inState, long currentId,
boolean restoreIncognitoTabs, boolean restoreAll) {
- if (currentTab == -1) {
+ if (currentId == -1) {
return;
}
-
- // If currentTab is valid, numTabs must be present.
- final int numTabs = inState.getInt(Tab.NUMTABS, -1);
-
- // Map saved tab indices to new indices, in case any incognito tabs
- // need to not be restored.
- HashMap<Integer, Integer> originalTabIndices = new HashMap<Integer, Integer>();
- originalTabIndices.put(-1, -1);
- for (int i = 0; i < numTabs; i++) {
- Bundle state = inState.getBundle(Tab.WEBVIEW + i);
-
- if (!restoreIncognitoTabs && state != null && state.getBoolean(Tab.INCOGNITO)) {
- originalTabIndices.put(i, -1);
- } else if (i == currentTab || restoreAll) {
+ long[] ids = inState.getLongArray(POSITIONS);
+ long maxId = -Long.MAX_VALUE;
+ HashMap<Long, Tab> tabMap = new HashMap<Long, Tab>();
+ for (long id : ids) {
+ if (id > maxId) {
+ maxId = id;
+ }
+ final String idkey = Long.toString(id);
+ Bundle state = inState.getBundle(idkey);
+ if (!restoreIncognitoTabs && state != null
+ && state.getBoolean(Tab.INCOGNITO)) {
+ // ignore tab
+ } else if (id == currentId || restoreAll) {
Tab t = createNewTab();
+ tabMap.put(id, t);
// Me must set the current tab before restoring the state
// so that all the client classes are set.
- if (i == currentTab) {
+ if (id == currentId) {
setCurrentTab(t);
}
if (!t.restoreState(state)) {
@@ -360,11 +358,12 @@
t.getWebView().loadUrl(BrowserSettings.getInstance()
.getHomePage());
}
- originalTabIndices.put(i, getTabCount() - 1);
} else {
// Create a new tab and don't restore the state yet, add it
// to the tab list
- Tab t = new Tab(mController, null, false, null, null);
+ Tab t = new Tab(mController, null);
+ t.setId(id);
+ tabMap.put(id, t);
if (state != null) {
t.setSavedState(state);
// Need to maintain the app id and original url so we
@@ -374,21 +373,22 @@
mTabs.add(t);
// added the tab to the front as they are not current
mTabQueue.add(0, t);
- originalTabIndices.put(i, getTabCount() - 1);
}
- }
+ // make sure that there is no id overlap between the restored
+ // and new tabs
+ sNextId = maxId + 1;
- // Rebuild the tree of tabs. Do this after all tabs have been
- // created/restored so that the parent tab exists.
- for (int i = 0; i < numTabs; i++) {
- final Bundle b = inState.getBundle(Tab.WEBVIEW + i);
- final Tab t = getTab(i);
- if (b != null && t != null) {
- final Integer parentIndex = originalTabIndices.get(b.getInt(Tab.PARENTTAB, -1));
- if (parentIndex != -1) {
- final Tab parent = getTab(parentIndex);
+ }
+ // restore parent/child relationships
+ for (long id : ids) {
+ final Tab tab = tabMap.get(id);
+ final Bundle b = inState.getBundle(Long.toString(id));
+ if ((b != null) && (tab != null)) {
+ final long parentId = b.getLong(Tab.PARENTTAB, -1);
+ if (parentId != -1) {
+ final Tab parent = tabMap.get(parentId);
if (parent != null) {
- parent.addChildTab(t);
+ parent.addChildTab(tab);
}
}
}
@@ -443,7 +443,7 @@
for (Tab t : mTabQueue) {
if (t != null && t.getWebView() != null) {
openTabCount++;
- if (t != current && t != current.getParentTab()) {
+ if (t != current && t != current.getParent()) {
tabsToGo.add(t);
}
}
@@ -462,9 +462,7 @@
* @param view The WebView used to find the tab.
*/
Tab getTabFromView(WebView view) {
- final int size = getTabCount();
- for (int i = 0; i < size; i++) {
- final Tab t = getTab(i);
+ for (Tab t : mTabs) {
if (t.getSubWebView() == view || t.getWebView() == view) {
return t;
}
@@ -476,13 +474,11 @@
* Return the tab with the matching application id.
* @param id The application identifier.
*/
- Tab getTabFromId(String id) {
+ Tab getTabFromAppId(String id) {
if (id == null) {
return null;
}
- final int size = getTabCount();
- for (int i = 0; i < size; i++) {
- final Tab t = getTab(i);
+ for (Tab t : mTabs) {
if (id.equals(t.getAppId())) {
return t;
}
@@ -494,9 +490,7 @@
* Stop loading in all opened WebView including subWindows.
*/
void stopAllLoading() {
- final int size = getTabCount();
- for (int i = 0; i < size; i++) {
- final Tab t = getTab(i);
+ for (Tab t : mTabs) {
final WebView webview = t.getWebView();
if (webview != null) {
webview.stopLoading();
@@ -539,10 +533,8 @@
return t;
}
// Now check all the rest.
- final int size = getTabCount();
- for (int i = 0; i < size; i++) {
- t = getTab(i);
- if (tabMatchesUrl(t, url)) {
+ for (Tab tab : mTabs) {
+ if (tabMatchesUrl(tab, url)) {
return t;
}
}
diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java
deleted file mode 100644
index 686416c..0000000
--- a/src/com/android/browser/TitleBar.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.speech.RecognizerIntent;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.style.ImageSpan;
-import android.view.ContextMenu;
-import android.view.LayoutInflater;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-
-/**
- * This class represents a title bar for a particular "tab" or "window" in the
- * browser.
- */
-public class TitleBar extends TitleBarBase implements OnFocusChangeListener,
- OnClickListener {
-
- private Activity mActivity;
- private ImageButton mBookmarkButton;
- private PageProgressView mHorizontalProgress;
- private ImageButton mStopButton;
- private Drawable mBookmarkDrawable;
- private Drawable mVoiceDrawable;
- private boolean mInLoad;
- private Intent mVoiceSearchIntent;
- private ImageSpan mArcsSpan;
-
- public TitleBar(Activity activity, UiController controller, PhoneUi ui) {
- super(activity, controller, ui);
- LayoutInflater factory = LayoutInflater.from(activity);
- factory.inflate(R.layout.title_bar, this);
- mActivity = activity;
-
- mUrlInput = (UrlInputView) findViewById(R.id.url_input);
- mUrlInput.setCompoundDrawablePadding(5);
- mUrlInput.setContainer(this);
- mUrlInput.setSelectAllOnFocus(true);
- mUrlInput.setController(mUiController);
- mUrlInput.setUrlInputListener(this);
- mUrlInput.setOnFocusChangeListener(this);
-
- mLockIcon = (ImageView) findViewById(R.id.lock);
- mFavicon = (ImageView) findViewById(R.id.favicon);
- mStopButton = (ImageButton) findViewById(R.id.stop);
- mBookmarkButton = (ImageButton) findViewById(R.id.bookmark);
- mStopButton.setOnClickListener(this);
- mBookmarkButton.setOnClickListener(this);
-
- mHorizontalProgress = (PageProgressView) findViewById(
- R.id.progress_horizontal);
- mVoiceSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- mVoiceSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
- RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
- // This extra tells voice search not to send the application id in its
- // results intent - http://b/2546173
- //
- // TODO: Make a constant for this extra.
- mVoiceSearchIntent.putExtra("android.speech.extras.SEND_APPLICATION_ID_EXTRA",
- false);
- PackageManager pm = activity.getPackageManager();
- ResolveInfo ri = pm.resolveActivity(mVoiceSearchIntent,
- PackageManager.MATCH_DEFAULT_ONLY);
- Resources resources = getResources();
- if (ri == null) {
- mVoiceSearchIntent = null;
- } else {
- mVoiceDrawable = resources.getDrawable(
- android.R.drawable.ic_btn_speak_now);
- }
- mBookmarkDrawable = mBookmarkButton.getDrawable();
- mArcsSpan = new ImageSpan(activity, R.drawable.arcs,
- ImageSpan.ALIGN_BASELINE);
- }
-
- @Override
- public void createContextMenu(ContextMenu menu) {
- MenuInflater inflater = mActivity.getMenuInflater();
- inflater.inflate(R.menu.title_context, menu);
- mActivity.onCreateContextMenu(menu, this, null);
- }
-
- /**
- * Change the TitleBar to or from voice mode. If there is no package to
- * handle voice search, the TitleBar cannot be set to voice mode.
- */
- @Override
- void setInVoiceMode(boolean inVoiceMode) {
- if (mInVoiceMode == inVoiceMode) return;
- mInVoiceMode = inVoiceMode && mVoiceSearchIntent != null;
- Drawable titleDrawable;
- if (mInVoiceMode) {
- mBookmarkButton.setImageDrawable(mVoiceDrawable);
- mUrlInput.setEllipsize(null);
- mBookmarkButton.setVisibility(View.VISIBLE);
- mStopButton.setVisibility(View.GONE);
- } else {
- if (mInLoad) {
- mBookmarkButton.setVisibility(View.GONE);
- mStopButton.setVisibility(View.VISIBLE);
- } else {
- mBookmarkButton.setVisibility(View.VISIBLE);
- mStopButton.setVisibility(View.GONE);
- mBookmarkButton.setImageDrawable(mBookmarkDrawable);
- }
- mUrlInput.setEllipsize(TextUtils.TruncateAt.END);
- }
- mUrlInput.setSingleLine(!mInVoiceMode);
- }
-
- /**
- * Update the progress, from 0 to 100.
- */
- @Override
- void setProgress(int newProgress) {
- if (newProgress >= PROGRESS_MAX) {
- mHorizontalProgress.setVisibility(View.GONE);
- if (!mInVoiceMode) {
- mBookmarkButton.setImageDrawable(mBookmarkDrawable);
- mBookmarkButton.setVisibility(View.VISIBLE);
- mStopButton.setVisibility(View.GONE);
- }
- mInLoad = false;
- } else {
- mHorizontalProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
- / PROGRESS_MAX);
- if (!mInLoad) {
- mHorizontalProgress.setVisibility(View.VISIBLE);
- if (!mInVoiceMode) {
- mBookmarkButton.setVisibility(View.GONE);
- mStopButton.setVisibility(View.VISIBLE);
- }
- mInLoad = true;
- }
- }
- }
-
- /**
- * Update the text displayed in the title bar.
- * @param title String to display. If null, the new tab string will be
- * shown.
- */
- @Override
- void setDisplayTitle(String title) {
- if (title == null) {
- mUrlInput.setText(R.string.new_tab);
- } else {
- if (mInVoiceMode) {
- // Add two spaces. The second one will be replaced with an
- // image, and the first one will put space between it and the
- // text
- SpannableString spannable = new SpannableString(title + " ");
- int end = spannable.length();
- spannable.setSpan(mArcsSpan, end - 1, end,
- Spanned.SPAN_MARK_POINT);
- mUrlInput.setText(spannable);
- } else {
- mUrlInput.setText(title);
- }
- }
- }
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (v == mUrlInput && hasFocus) {
- mActivity.closeOptionsMenu();
- }
- }
-
- @Override
- public void onClick(View v) {
- if (v == mStopButton) {
- mUiController.stopLoading();
- } else if (v == mBookmarkButton) {
- mUiController.bookmarkCurrentPage(AddBookmarkPage.DEFAULT_FOLDER_ID,
- true);
- }
- }
-
- @Override
- public void setCurrentUrlIsBookmark(boolean isBookmark) {
- mBookmarkButton.setActivated(isBookmark);
- }
-}
diff --git a/src/com/android/browser/TitleBarBase.java b/src/com/android/browser/TitleBarBase.java
index b905d4e..4dc960c 100644
--- a/src/com/android/browser/TitleBarBase.java
+++ b/src/com/android/browser/TitleBarBase.java
@@ -16,27 +16,51 @@
package com.android.browser;
+import com.android.browser.UI.DropdownChangeListener;
import com.android.browser.UrlInputView.UrlInputListener;
+import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.PaintDrawable;
import android.os.Bundle;
import android.speech.RecognizerResultsIntent;
+import android.text.TextUtils;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.view.animation.AnimationUtils;
+import android.webkit.WebView;
+import android.widget.AbsoluteLayout;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import java.util.List;
/**
* Base class for a title bar used by the browser.
*/
-public class TitleBarBase extends LinearLayout implements UrlInputListener {
+public class TitleBarBase extends RelativeLayout
+ implements OnClickListener, OnFocusChangeListener, UrlInputListener,
+ TextChangeWatcher, DeviceAccountLogin.AutoLoginCallback {
protected static final int PROGRESS_MAX = 100;
@@ -44,22 +68,206 @@
protected ImageView mFavicon;
protected ImageView mLockIcon;
- protected Drawable mGenericFavicon;
protected UiController mUiController;
protected BaseUi mBaseUi;
+ protected FrameLayout mParent;
+ protected PageProgressView mProgress;
protected UrlInputView mUrlInput;
protected boolean mInVoiceMode;
+ protected View mContainer;
- public TitleBarBase(Context context, UiController controller, BaseUi ui) {
+
+ // Auto-login UI
+ protected View mAutoLogin;
+ protected Spinner mAutoLoginAccount;
+ protected Button mAutoLoginLogin;
+ protected ProgressBar mAutoLoginProgress;
+ protected TextView mAutoLoginError;
+ protected View mAutoLoginCancel;
+ protected DeviceAccountLogin mAutoLoginHandler;
+ protected ArrayAdapter<String> mAccountsAdapter;
+ protected boolean mUseQuickControls;
+
+ //state
+ protected boolean mShowing;
+ protected boolean mInLoad;
+ protected boolean mSkipTitleBarAnimations;
+ private Animator mTitleBarAnimator;
+
+ public TitleBarBase(Context context, UiController controller, BaseUi ui,
+ FrameLayout parent) {
super(context, null);
mUiController = controller;
mBaseUi = ui;
- mGenericFavicon = context.getResources().getDrawable(
- R.drawable.app_web_browser_sm);
+ mParent = parent;
}
- /* package */ void setProgress(int newProgress) {}
- /* package */ void setDisplayTitle(String title) {}
+ protected void initLayout(Context context, int layoutId) {
+ LayoutInflater factory = LayoutInflater.from(context);
+ factory.inflate(layoutId, this);
+ mContainer = findViewById(R.id.taburlbar);
+ mProgress = (PageProgressView) findViewById(R.id.progress);
+ mUrlInput = (UrlInputView) findViewById(R.id.url);
+ mLockIcon = (ImageView) findViewById(R.id.lock);
+ mUrlInput.setUrlInputListener(this);
+ mUrlInput.setController(mUiController);
+ mUrlInput.setOnFocusChangeListener(this);
+ mUrlInput.setSelectAllOnFocus(true);
+ mUrlInput.addQueryTextWatcher(this);
+ mAutoLogin = findViewById(R.id.autologin);
+ mAutoLoginAccount = (Spinner) findViewById(R.id.autologin_account);
+ mAutoLoginLogin = (Button) findViewById(R.id.autologin_login);
+ mAutoLoginLogin.setOnClickListener(this);
+ mAutoLoginProgress = (ProgressBar) findViewById(R.id.autologin_progress);
+ mAutoLoginError = (TextView) findViewById(R.id.autologin_error);
+ mAutoLoginCancel = mAutoLogin.findViewById(R.id.autologin_close);
+ mAutoLoginCancel.setOnClickListener(this);
+ }
+
+ protected void setupUrlInput() {
+ }
+
+ protected void setUseQuickControls(boolean use) {
+ mUseQuickControls = use;
+ setLayoutParams(makeLayoutParams());
+ }
+
+ void setShowProgressOnly(boolean progress) {
+ if (progress && !inAutoLogin()) {
+ mContainer.setVisibility(View.GONE);
+ } else {
+ mContainer.setVisibility(View.VISIBLE);
+ }
+ }
+
+ void setSkipTitleBarAnimations(boolean skip) {
+ mSkipTitleBarAnimations = skip;
+ }
+
+ void show() {
+ if (mUseQuickControls) {
+ mParent.addView(this);
+ } else {
+ if (!mSkipTitleBarAnimations) {
+ cancelTitleBarAnimation(false);
+ int visibleHeight = getVisibleTitleHeight();
+ float startPos = (-getEmbeddedHeight() + visibleHeight);
+ if (getTranslationY() != 0) {
+ startPos = Math.max(startPos, getTranslationY());
+ }
+ mTitleBarAnimator = ObjectAnimator.ofFloat(this,
+ "translationY",
+ startPos, 0);
+ mTitleBarAnimator.start();
+ }
+ mBaseUi.setTitleGravity(Gravity.TOP);
+ }
+ mShowing = true;
+ }
+
+ void hide() {
+ if (mUseQuickControls) {
+ mParent.removeView(this);
+ } else {
+ if (!mSkipTitleBarAnimations) {
+ cancelTitleBarAnimation(false);
+ int visibleHeight = getVisibleTitleHeight();
+ mTitleBarAnimator = ObjectAnimator.ofFloat(this,
+ "translationY", getTranslationY(),
+ (-getEmbeddedHeight() + visibleHeight));
+ mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
+ mTitleBarAnimator.start();
+ } else {
+ mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
+ }
+ }
+ mShowing = false;
+ }
+
+ boolean isShowing() {
+ return mShowing;
+ }
+
+ void cancelTitleBarAnimation(boolean reset) {
+ if (mTitleBarAnimator != null) {
+ mTitleBarAnimator.cancel();
+ mTitleBarAnimator = null;
+ }
+ if (reset) {
+ setTranslationY(0);
+ }
+ }
+
+ private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
+
+ boolean mWasCanceled;
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mWasCanceled = false;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mWasCanceled) {
+ setTranslationY(0);
+ }
+ mBaseUi.setTitleGravity(Gravity.NO_GRAVITY);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mWasCanceled = true;
+ }
+ };
+
+ private int getVisibleTitleHeight() {
+ Tab tab = mBaseUi.getActiveTab();
+ WebView webview = tab != null ? tab.getWebView() : null;
+ return webview != null ? webview.getVisibleTitleHeight() : 0;
+ }
+
+ /**
+ * Update the progress, from 0 to 100.
+ */
+ void setProgress(int newProgress) {
+ if (newProgress >= PROGRESS_MAX) {
+ mProgress.setProgress(PageProgressView.MAX_PROGRESS);
+ mProgress.setVisibility(View.GONE);
+ mInLoad = false;
+ onProgressStopped();
+ // check if needs to be hidden
+ if (!isEditingUrl() && !inAutoLogin()) {
+ hide();
+ if (mUseQuickControls) {
+ setShowProgressOnly(false);
+ }
+ }
+ } else {
+ if (!mInLoad) {
+ mProgress.setVisibility(View.VISIBLE);
+ mInLoad = true;
+ onProgressStarted();
+ }
+ mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
+ / PROGRESS_MAX);
+ if (!mShowing) {
+ if (mUseQuickControls && !isEditingUrl()) {
+ setShowProgressOnly(true);
+ }
+ show();
+ }
+ }
+ }
+
+ protected void onProgressStarted() {
+ }
+
+ protected void onProgressStopped() {
+ }
/* package */ void setLock(Drawable d) {
assert mLockIcon != null;
@@ -72,28 +280,206 @@
}
/* package */ void setFavicon(Bitmap icon) {
- assert mFavicon != null;
- Drawable[] array = new Drawable[3];
- array[0] = new PaintDrawable(Color.BLACK);
- PaintDrawable p = new PaintDrawable(Color.WHITE);
- array[1] = p;
- if (icon == null) {
- array[2] = mGenericFavicon;
- } else {
- array[2] = new BitmapDrawable(icon);
- }
- LayerDrawable d = new LayerDrawable(array);
- d.setLayerInset(1, 1, 1, 1, 1);
- d.setLayerInset(2, 2, 2, 2, 2);
- mFavicon.setImageDrawable(d);
+ mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon));
}
- /* package */ void setInVoiceMode(boolean inVoiceMode) {}
-
- /* package */ void setIncognitoMode(boolean incognito) {}
-
public int getEmbeddedHeight() {
- return getHeight();
+ int height = mContainer.getHeight();
+ if (mAutoLogin.getVisibility() == View.VISIBLE) {
+ height += mAutoLogin.getHeight();
+ }
+ return height;
+ }
+
+ protected void updateAutoLogin(Tab tab, boolean animate) {
+ DeviceAccountLogin login = tab.getDeviceAccountLogin();
+ if (login != null) {
+ mAutoLoginHandler = login;
+ ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext,
+ android.R.style.Theme_Holo_Light);
+ mAccountsAdapter = new ArrayAdapter<String>(wrapper,
+ android.R.layout.simple_spinner_item, login.getAccountNames());
+ mAccountsAdapter.setDropDownViewResource(
+ android.R.layout.simple_spinner_dropdown_item);
+ mAutoLoginAccount.setAdapter(mAccountsAdapter);
+ mAutoLoginAccount.setSelection(0);
+ mAutoLoginAccount.setEnabled(true);
+ mAutoLoginLogin.setEnabled(true);
+ mAutoLoginProgress.setVisibility(View.INVISIBLE);
+ mAutoLoginError.setVisibility(View.GONE);
+ switch (login.getState()) {
+ case DeviceAccountLogin.PROCESSING:
+ mAutoLoginAccount.setEnabled(false);
+ mAutoLoginLogin.setEnabled(false);
+ mAutoLoginProgress.setVisibility(View.VISIBLE);
+ break;
+ case DeviceAccountLogin.FAILED:
+ mAutoLoginProgress.setVisibility(View.INVISIBLE);
+ mAutoLoginError.setVisibility(View.VISIBLE);
+ break;
+ case DeviceAccountLogin.INITIAL:
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ showAutoLogin(animate);
+ } else {
+ hideAutoLogin(animate);
+ }
+ }
+
+ protected void showAutoLogin(boolean animate) {
+ if (mUseQuickControls) {
+ mBaseUi.showTitleBar();
+ }
+ mAutoLogin.setVisibility(View.VISIBLE);
+ if (animate) {
+ mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
+ getContext(), R.anim.autologin_enter));
+ }
+ }
+
+ protected void hideAutoLogin(boolean animate) {
+ mAutoLoginHandler = null;
+ if (mUseQuickControls) {
+ mBaseUi.hideTitleBar();
+ mAutoLogin.setVisibility(View.GONE);
+ mBaseUi.refreshWebView();
+ } else {
+ if (animate) {
+ Animation anim = AnimationUtils.loadAnimation(getContext(),
+ R.anim.autologin_exit);
+ anim.setAnimationListener(new AnimationListener() {
+ @Override
+ public void onAnimationEnd(Animation a) {
+ mAutoLogin.setVisibility(View.GONE);
+ mBaseUi.refreshWebView();
+ }
+
+ @Override
+ public void onAnimationStart(Animation a) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation a) {
+ }
+ });
+ mAutoLogin.startAnimation(anim);
+ } else if (mAutoLogin.getAnimation() == null) {
+ mAutoLogin.setVisibility(View.GONE);
+ mBaseUi.refreshWebView();
+ }
+ }
+ }
+
+ @Override
+ public void loginFailed() {
+ mAutoLoginAccount.setEnabled(true);
+ mAutoLoginLogin.setEnabled(true);
+ mAutoLoginProgress.setVisibility(View.INVISIBLE);
+ mAutoLoginError.setVisibility(View.VISIBLE);
+ }
+
+
+ protected boolean inAutoLogin() {
+ return mAutoLoginHandler != null;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mAutoLoginCancel == v) {
+ if (mAutoLoginHandler != null) {
+ mAutoLoginHandler.cancel();
+ mAutoLoginHandler = null;
+ }
+ hideAutoLogin(true);
+ } else if (mAutoLoginLogin == v) {
+ if (mAutoLoginHandler != null) {
+ mAutoLoginAccount.setEnabled(false);
+ mAutoLoginLogin.setEnabled(false);
+ mAutoLoginProgress.setVisibility(View.VISIBLE);
+ mAutoLoginError.setVisibility(View.GONE);
+ mAutoLoginHandler.login(
+ mAutoLoginAccount.getSelectedItemPosition(), this);
+ }
+ }
+ }
+
+ @Override
+ public void onFocusChange(View view, boolean hasFocus) {
+ // if losing focus and not in touch mode, leave as is
+ if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
+ setFocusState(hasFocus);
+ }
+ if (hasFocus) {
+ mUrlInput.forceIme();
+ if (mInVoiceMode) {
+ mUrlInput.forceFilter();
+ }
+ } else if (!mUrlInput.needsUpdate()) {
+ mUrlInput.dismissDropDown();
+ mUrlInput.hideIME();
+ if (mUrlInput.getText().length() == 0) {
+ Tab currentTab = mUiController.getTabControl().getCurrentTab();
+ if (currentTab != null) {
+ mUrlInput.setText(currentTab.getUrl(), false);
+ }
+ }
+ }
+ mUrlInput.clearNeedsUpdate();
+ }
+
+ protected void setFocusState(boolean focus) {
+ if (focus) {
+ updateSearchMode(false);
+ }
+ }
+
+ protected void updateSearchMode(boolean userEdited) {
+ setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText()));
+ }
+
+ protected void setSearchMode(boolean voiceSearchEnabled) {}
+
+ boolean isEditingUrl() {
+ return mUrlInput.hasFocus();
+ }
+
+ void stopEditingUrl() {
+ mUrlInput.clearFocus();
+ }
+
+ void setDisplayTitle(String title) {
+ if (!isEditingUrl()) {
+ mUrlInput.setText(title, false);
+ }
+ }
+
+ // UrlInput text watcher
+
+ @Override
+ public void onTextChanged(String newText) {
+ if (mUrlInput.hasFocus()) {
+ // check if input field is empty and adjust voice search state
+ updateSearchMode(true);
+ // clear voice mode when user types
+ setInVoiceMode(false, null);
+ }
+ }
+
+ // voicesearch
+
+ public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
+ mInVoiceMode = voicemode;
+ mUrlInput.setVoiceResults(voiceResults);
+ }
+
+ void setIncognitoMode(boolean incognito) {
+ mUrlInput.setIncognitoMode(incognito);
+ }
+
+ void clearCompletions() {
+ mUrlInput.setSuggestedText(null);
}
// UrlInputListener implementation
@@ -157,4 +543,58 @@
public void setCurrentUrlIsBookmark(boolean isBookmark) {
}
+ @Override
+ public boolean dispatchKeyEventPreIme(KeyEvent evt) {
+ if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ // catch back key in order to do slightly more cleanup than usual
+ mUrlInput.clearFocus();
+ return true;
+ }
+ return super.dispatchKeyEventPreIme(evt);
+ }
+
+ protected WebView getCurrentWebView() {
+ Tab t = mBaseUi.getActiveTab();
+ if (t != null) {
+ return t.getWebView();
+ } else {
+ return null;
+ }
+ }
+
+ void registerDropdownChangeListener(DropdownChangeListener d) {
+ mUrlInput.registerDropdownChangeListener(d);
+ }
+
+ /**
+ * called from the Ui when the user wants to edit
+ * @param clearInput clear the input field
+ */
+ void startEditingUrl(boolean clearInput) {
+ // editing takes preference of progress
+ mContainer.setVisibility(View.VISIBLE);
+ if (mUseQuickControls) {
+ mProgress.setVisibility(View.GONE);
+ }
+ if (!mUrlInput.hasFocus()) {
+ mUrlInput.requestFocus();
+ }
+ if (clearInput) {
+ mUrlInput.setText("");
+ } else if (mInVoiceMode) {
+ mUrlInput.showDropDown();
+ }
+ }
+
+ private ViewGroup.LayoutParams makeLayoutParams() {
+ if (mUseQuickControls) {
+ return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.WRAP_CONTENT);
+ } else {
+ return new AbsoluteLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
+ 0, 0);
+ }
+ }
+
}
diff --git a/src/com/android/browser/TitleBarPhone.java b/src/com/android/browser/TitleBarPhone.java
new file mode 100644
index 0000000..97fe747
--- /dev/null
+++ b/src/com/android/browser/TitleBarPhone.java
@@ -0,0 +1,191 @@
+/*
+ * 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 com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.webkit.WebView;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+
+import java.util.List;
+
+/**
+ * This class represents a title bar for a particular "tab" or "window" in the
+ * browser.
+ */
+public class TitleBarPhone extends TitleBarBase implements OnFocusChangeListener,
+ OnClickListener, TextChangeWatcher {
+
+ private Activity mActivity;
+ private ImageView mStopButton;
+ private ImageView mVoiceButton;
+ private boolean mHasLockIcon;
+ private ImageButton mForward;
+ private Drawable mStopDrawable;
+ private Drawable mRefreshDrawable;
+
+ public TitleBarPhone(Activity activity, UiController controller, PhoneUi ui,
+ FrameLayout parent) {
+ super(activity, controller, ui, parent);
+ mActivity = activity;
+ initLayout(activity, R.layout.title_bar);
+ }
+
+ @Override
+ protected void initLayout(Context context, int layoutId) {
+ super.initLayout(context, layoutId);
+ mLockIcon = (ImageView) findViewById(R.id.lock);
+ mFavicon = (ImageView) findViewById(R.id.favicon);
+ mStopButton = (ImageView) findViewById(R.id.stop);
+ mStopButton.setOnClickListener(this);
+ mVoiceButton = (ImageView) findViewById(R.id.voice);
+ mVoiceButton.setOnClickListener(this);
+ mForward = (ImageButton) findViewById(R.id.forward);
+ mForward.setOnClickListener(this);
+ setFocusState(false);
+ Resources res = context.getResources();
+ mStopDrawable = res.getDrawable(R.drawable.ic_stop_holo_dark);
+ mRefreshDrawable = res.getDrawable(R.drawable.ic_refresh_holo_dark);
+ }
+
+ @Override
+ public void createContextMenu(ContextMenu menu) {
+ MenuInflater inflater = mActivity.getMenuInflater();
+ inflater.inflate(R.menu.title_context, menu);
+ mActivity.onCreateContextMenu(menu, this, null);
+ }
+
+ @Override
+ public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
+ super.setInVoiceMode(voicemode, voiceResults);
+ }
+
+ @Override
+ protected void setSearchMode(boolean voiceSearchEnabled) {
+ boolean showvoicebutton = voiceSearchEnabled &&
+ mUiController.supportsVoiceSearch();
+ mVoiceButton.setVisibility(showvoicebutton ? View.VISIBLE :
+ View.GONE);
+ }
+
+ @Override
+ protected void setFocusState(boolean focus) {
+ super.setFocusState(focus);
+ if (focus) {
+ mHasLockIcon = (mLockIcon.getVisibility() == View.VISIBLE);
+ mLockIcon.setVisibility(View.GONE);
+ mStopButton.setVisibility(View.GONE);
+ mVoiceButton.setVisibility(View.VISIBLE);
+ } else {
+ mLockIcon.setVisibility(mHasLockIcon ? View.VISIBLE : View.GONE);
+ mStopButton.setVisibility(View.VISIBLE);
+ mVoiceButton.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ protected void onProgressStarted() {
+ setFocusState(mUrlInput.hasFocus());
+ }
+
+ @Override
+ protected void onProgressStopped() {
+ setFocusState(mUrlInput.hasFocus());
+ }
+
+ @Override
+ void setProgress(int progress) {
+ super.setProgress(progress);
+ if (progress == 100) {
+ mStopButton.setImageDrawable(mRefreshDrawable);
+ } else if (mStopButton.getDrawable() != mStopDrawable) {
+ mStopButton.setImageDrawable(mStopDrawable);
+ }
+ updateNavigationState();
+ }
+
+ /**
+ * Update the text displayed in the title bar.
+ * @param title String to display. If null, the new tab string will be
+ * shown.
+ */
+ @Override
+ void setDisplayTitle(String title) {
+ if (title == null) {
+ mUrlInput.setText(R.string.new_tab);
+ } else {
+ mUrlInput.setText(title);
+ }
+ mUrlInput.setSelection(0);
+ updateNavigationState();
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (v == mUrlInput) {
+ if (hasFocus) {
+ mActivity.closeOptionsMenu();
+ }
+ }
+ super.onFocusChange(v, hasFocus);
+ if (!hasFocus) {
+ mBaseUi.hideTitleBar();
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mStopButton) {
+ if (mInLoad) {
+ mUiController.stopLoading();
+ } else {
+ WebView web = mBaseUi.getWebView();
+ if (web != null) {
+ web.reload();
+ }
+ }
+ } else if (v == mVoiceButton) {
+ mUiController.startVoiceSearch();
+ } else if (v == mForward) {
+ WebView web = mBaseUi.getWebView();
+ if (web != null) {
+ web.goForward();
+ }
+ } else {
+ super.onClick(v);
+ }
+ }
+
+ private void updateNavigationState() {
+ WebView web = mBaseUi.getWebView();
+ if (web != null) {
+ mForward.setVisibility(web.canGoForward() ? View.VISIBLE : View.GONE);
+ }
+ }
+
+}
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index e91597f..8c03e4c 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -16,41 +16,24 @@
package com.android.browser;
-import com.android.browser.UI.DropdownChangeListener;
import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
-import com.android.browser.search.SearchEngine;
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
-import android.content.res.Configuration;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.preference.PreferenceManager;
import android.text.TextUtils;
-import android.view.ContextThemeWrapper;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
-import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.Animation.AnimationListener;
-import android.view.animation.AnimationUtils;
import android.webkit.WebView;
-import android.widget.AbsoluteLayout;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.TextView;
import java.util.List;
@@ -66,39 +49,25 @@
private Drawable mStopDrawable;
private Drawable mReloadDrawable;
- private View mContainer;
+ private View mUrlContainer;
private ImageButton mBackButton;
private ImageButton mForwardButton;
private ImageView mStar;
private ImageView mUrlIcon;
private ImageView mSearchButton;
- private View mUrlContainer;
- private View mNavButtons;
private View mGoButton;
private ImageView mStopButton;
private View mAllButton;
private View mClearButton;
private ImageView mVoiceSearch;
- private PageProgressView mProgressView;
private Drawable mFocusDrawable;
private Drawable mUnfocusDrawable;
- // Auto-login UI
- private View mAutoLogin;
- private Spinner mAutoLoginAccount;
- private Button mAutoLoginLogin;
- private ProgressBar mAutoLoginProgress;
- private TextView mAutoLoginError;
- private ImageButton mAutoLoginCancel;
- private DeviceAccountLogin mAutoLoginHandler;
- private ArrayAdapter<String> mAccountsAdapter;
-
- private boolean mInLoad;
- private boolean mUseQuickControls;
- private boolean mHideNavButtons;
+ private boolean mHasFocus = false;
+ private BrowserSettings mSettings;
public TitleBarXLarge(Activity activity, UiController controller,
- XLargeUi ui) {
- super(activity, controller, ui);
+ XLargeUi ui, FrameLayout parent) {
+ super(activity, controller, ui, parent);
mUi = ui;
Resources resources = activity.getResources();
mStopDrawable = resources.getDrawable(R.drawable.ic_stop_holo_dark);
@@ -108,17 +77,15 @@
mUnfocusDrawable = resources.getDrawable(
R.drawable.textfield_default_holo_dark);
mInVoiceMode = false;
- initLayout(activity);
+ mSettings = BrowserSettings.getInstance();
+ initLayout(activity, R.layout.url_bar);
+ PreferenceManager.getDefaultSharedPreferences(activity)
+ .registerOnSharedPreferenceChangeListener(mSharedPrefsListener);
}
- private void initLayout(Context context) {
- Resources res = mContext.getResources();
- mHideNavButtons = res.getBoolean(R.bool.hide_nav_buttons);
- LayoutInflater factory = LayoutInflater.from(context);
- factory.inflate(R.layout.url_bar, this);
-
- mContainer = findViewById(R.id.taburlbar);
- mUrlInput = (UrlInputView) findViewById(R.id.url_focused);
+ @Override
+ protected void initLayout(Context context, int layoutId) {
+ super.initLayout(context, layoutId);
mAllButton = findViewById(R.id.all_btn);
// TODO: Change enabled states based on whether you can go
// back/forward. Probably should be done inside onPageStarted.
@@ -132,8 +99,6 @@
mGoButton = findViewById(R.id.go);
mClearButton = findViewById(R.id.clear);
mVoiceSearch = (ImageView) findViewById(R.id.voicesearch);
- mProgressView = (PageProgressView) findViewById(R.id.progress);
- mNavButtons = findViewById(R.id.navbuttons);
mUrlContainer = findViewById(R.id.urlbar_focused);
mBackButton.setOnClickListener(this);
mForwardButton.setOnClickListener(this);
@@ -144,45 +109,11 @@
mGoButton.setOnClickListener(this);
mClearButton.setOnClickListener(this);
mVoiceSearch.setOnClickListener(this);
- mUrlInput.setUrlInputListener(this);
+ mUrlIcon.setOnClickListener(this);
mUrlInput.setContainer(mUrlContainer);
- mUrlInput.setController(mUiController);
- mUrlInput.setOnFocusChangeListener(this);
- mUrlInput.setSelectAllOnFocus(true);
- mUrlInput.addQueryTextWatcher(this);
- mAutoLogin = findViewById(R.id.autologin);
- mAutoLoginAccount = (Spinner) findViewById(R.id.autologin_account);
- mAutoLoginLogin = (Button) findViewById(R.id.autologin_login);
- mAutoLoginLogin.setOnClickListener(this);
- mAutoLoginProgress =
- (ProgressBar) findViewById(R.id.autologin_progress);
- mAutoLoginError = (TextView) findViewById(R.id.autologin_error);
- mAutoLoginCancel =
- (ImageButton) mAutoLogin.findViewById(R.id.autologin_close);
- mAutoLoginCancel.setOnClickListener(this);
-
setFocusState(false);
}
- @Override
- public void onConfigurationChanged(Configuration config) {
- super.onConfigurationChanged(config);
- Resources res = mContext.getResources();
- mHideNavButtons = res.getBoolean(R.bool.hide_nav_buttons);
- if (mUrlInput.hasFocus()) {
- if (mHideNavButtons && (mNavButtons.getVisibility() == View.VISIBLE)) {
- int aw = mNavButtons.getMeasuredWidth();
- mNavButtons.setVisibility(View.GONE);
- mNavButtons.setAlpha(0f);
- mNavButtons.setTranslationX(-aw);
- } else if (!mHideNavButtons && (mNavButtons.getVisibility() == View.GONE)) {
- mNavButtons.setVisibility(View.VISIBLE);
- mNavButtons.setAlpha(1f);
- mNavButtons.setTranslationX(0);
- }
- }
- }
-
void updateNavigationState(Tab tab) {
WebView web = tab.getWebView();
if (web != null) {
@@ -193,100 +124,7 @@
? R.drawable.ic_forward_holo_dark
: R.drawable.ic_forward_disabled_holo_dark);
}
- }
-
- void updateAutoLogin(Tab tab, boolean animate) {
- DeviceAccountLogin login = tab.getDeviceAccountLogin();
- if (login != null) {
- mAutoLoginHandler = login;
- mAutoLogin.setVisibility(View.VISIBLE);
- ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext,
- android.R.style.Theme_Holo_Light);
- mAccountsAdapter = new ArrayAdapter<String>(wrapper,
- android.R.layout.simple_spinner_item, login.getAccountNames());
- mAccountsAdapter.setDropDownViewResource(
- android.R.layout.simple_spinner_dropdown_item);
- mAutoLoginAccount.setAdapter(mAccountsAdapter);
- mAutoLoginAccount.setSelection(0);
- mAutoLoginAccount.setEnabled(true);
- mAutoLoginLogin.setEnabled(true);
- mAutoLoginProgress.setVisibility(View.GONE);
- mAutoLoginError.setVisibility(View.GONE);
- switch (login.getState()) {
- case DeviceAccountLogin.PROCESSING:
- mAutoLoginAccount.setEnabled(false);
- mAutoLoginLogin.setEnabled(false);
- mAutoLoginProgress.setVisibility(View.VISIBLE);
- break;
- case DeviceAccountLogin.FAILED:
- mAutoLoginProgress.setVisibility(View.GONE);
- mAutoLoginError.setVisibility(View.VISIBLE);
- break;
- case DeviceAccountLogin.INITIAL:
- break;
- default:
- throw new IllegalStateException();
- }
- if (mUseQuickControls) {
- mUi.showTitleBar();
- } else {
- if (animate) {
- mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
- getContext(), R.anim.autologin_enter));
- }
- }
- } else {
- mAutoLoginHandler = null;
- if (mUseQuickControls) {
- mUi.hideTitleBar();
- mAutoLogin.setVisibility(View.GONE);
- mUi.refreshWebView();
- } else {
- if (animate) {
- hideAutoLogin();
- } else if (mAutoLogin.getAnimation() == null) {
- mAutoLogin.setVisibility(View.GONE);
- mUi.refreshWebView();
- }
- }
- }
- }
-
- boolean inAutoLogin() {
- return mAutoLoginHandler != null;
- }
-
- private ViewGroup.LayoutParams makeLayoutParams() {
- if (mUseQuickControls) {
- return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.WRAP_CONTENT);
- } else {
- return new AbsoluteLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
- 0, 0);
- }
- }
-
- @Override
- public int getEmbeddedHeight() {
- int height = mContainer.getHeight();
- if (mAutoLogin.getVisibility() == View.VISIBLE) {
- height += mAutoLogin.getHeight();
- }
- return height;
- }
-
- void setUseQuickControls(boolean useQuickControls) {
- mUseQuickControls = useQuickControls;
- setLayoutParams(makeLayoutParams());
- }
-
- void setShowProgressOnly(boolean progress) {
- if (progress && !inAutoLogin()) {
- mContainer.setVisibility(View.GONE);
- } else {
- mContainer.setVisibility(View.VISIBLE);
- }
+ updateUrlIcon();
}
@Override
@@ -324,47 +162,6 @@
mStar.setActivated(isBookmark);
}
- /**
- * called from the Ui when the user wants to edit
- * @param clearInput clear the input field
- */
- void startEditingUrl(boolean clearInput) {
- // editing takes preference of progress
- mContainer.setVisibility(View.VISIBLE);
- if (mUseQuickControls) {
- mProgressView.setVisibility(View.GONE);
- }
- if (!mUrlInput.hasFocus()) {
- mUrlInput.requestFocus();
- }
- if (clearInput) {
- mUrlInput.setText("");
- } else if (mInVoiceMode) {
- mUrlInput.showDropDown();
- }
- }
-
- boolean isEditingUrl() {
- return mUrlInput.hasFocus();
- }
-
- void stopEditingUrl() {
- mUrlInput.clearFocus();
- }
-
- private void hideAutoLogin() {
- Animation anim = AnimationUtils.loadAnimation(
- getContext(), R.anim.autologin_exit);
- anim.setAnimationListener(new AnimationListener() {
- @Override public void onAnimationEnd(Animation a) {
- mAutoLogin.setVisibility(View.GONE);
- mUi.refreshWebView();
- }
- @Override public void onAnimationStart(Animation a) {}
- @Override public void onAnimationRepeat(Animation a) {}
- });
- mAutoLogin.startAnimation(anim);
- }
@Override
public void onClick(View v) {
@@ -390,33 +187,19 @@
clearOrClose();
} else if (mVoiceSearch == v) {
mUiController.startVoiceSearch();
- } else if (mAutoLoginCancel == v) {
- if (mAutoLoginHandler != null) {
- mAutoLoginHandler.cancel();
- mAutoLoginHandler = null;
+ } else if (mUrlIcon == v) {
+ WebView web = mUiController.getCurrentWebView();
+ if (mSettings.enableUseragentSwitcher() && web != null) {
+ mSettings.toggleDesktopUseragent(web);
+ web.loadUrl(web.getOriginalUrl());
+ updateUrlIcon();
}
- hideAutoLogin();
- } else if (mAutoLoginLogin == v) {
- if (mAutoLoginHandler != null) {
- mAutoLoginAccount.setEnabled(false);
- mAutoLoginLogin.setEnabled(false);
- mAutoLoginProgress.setVisibility(View.VISIBLE);
- mAutoLoginError.setVisibility(View.GONE);
- mAutoLoginHandler.login(
- mAutoLoginAccount.getSelectedItemPosition(), this);
- }
+ } else {
+ super.onClick(v);
}
}
@Override
- public void loginFailed() {
- mAutoLoginAccount.setEnabled(true);
- mAutoLoginLogin.setEnabled(true);
- mAutoLoginProgress.setVisibility(View.GONE);
- mAutoLoginError.setVisibility(View.VISIBLE);
- }
-
- @Override
void setFavicon(Bitmap icon) { }
private void clearOrClose() {
@@ -429,22 +212,46 @@
}
}
- private void setFocusState(boolean focus) {
- if (focus) {
- if (mHideNavButtons) {
- hideNavButtons();
+ void updateUrlIcon() {
+ if (mHasFocus) {
+ return;
+ }
+ if (!mInVoiceMode && mSettings.enableUseragentSwitcher()) {
+ WebView web = mUiController.getCurrentWebView();
+ if (mSettings.hasDesktopUseragent(web)) {
+ mUrlIcon.setImageResource(R.drawable.ic_ua_desktop);
+ } else {
+ mUrlIcon.setImageResource(R.drawable.ic_ua_android);
}
- mUrlInput.setDropDownWidth(mUrlContainer.getWidth());
- mUrlInput.setDropDownHorizontalOffset(-mUrlInput.getLeft());
+ } else {
+ mUrlIcon.setImageResource(mInVoiceMode ?
+ R.drawable.ic_search_holo_dark
+ : R.drawable.ic_web_holo_dark);
+ }
+ }
+
+ private OnSharedPreferenceChangeListener mSharedPrefsListener =
+ new OnSharedPreferenceChangeListener() {
+
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ updateUrlIcon();
+ }
+
+ };
+
+ @Override
+ protected void setFocusState(boolean focus) {
+ super.setFocusState(focus);
+ mHasFocus = focus;
+ if (focus) {
mSearchButton.setVisibility(View.GONE);
mStar.setVisibility(View.GONE);
mClearButton.setVisibility(View.VISIBLE);
mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark);
updateSearchMode(false);
} else {
- if (mHideNavButtons) {
- showNavButtons();
- }
mGoButton.setVisibility(View.GONE);
mVoiceSearch.setVisibility(View.GONE);
mStar.setVisibility(View.VISIBLE);
@@ -454,9 +261,7 @@
} else {
mSearchButton.setVisibility(View.VISIBLE);
}
- mUrlIcon.setImageResource(mInVoiceMode ?
- R.drawable.ic_search_holo_dark
- : R.drawable.ic_web_holo_dark);
+ updateUrlIcon();
}
}
@@ -468,41 +273,25 @@
}
}
- /**
- * Update the progress, from 0 to 100.
- */
@Override
- void setProgress(int newProgress) {
- boolean blockvisuals = mUseQuickControls && isEditingUrl();
- if (newProgress >= PROGRESS_MAX) {
- if (!blockvisuals) {
- mProgressView.setProgress(PageProgressView.MAX_PROGRESS);
- mProgressView.setVisibility(View.GONE);
- mStopButton.setImageDrawable(mReloadDrawable);
- }
- mInLoad = false;
- } else {
- if (!mInLoad) {
- if (!blockvisuals) {
- mProgressView.setVisibility(View.VISIBLE);
- mStopButton.setImageDrawable(mStopDrawable);
- }
- mInLoad = true;
- }
- mProgressView.setProgress(newProgress * PageProgressView.MAX_PROGRESS
- / PROGRESS_MAX);
- }
+ protected void onProgressStarted() {
+ mStopButton.setImageDrawable(mStopDrawable);
}
- private void updateSearchMode(boolean userEdited) {
+ @Override
+ protected void onProgressStopped() {
+ mStopButton.setImageDrawable(mReloadDrawable);
+ }
+
+ @Override
+ protected void updateSearchMode(boolean userEdited) {
setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText()));
}
- private void setSearchMode(boolean voiceSearchEnabled) {
- SearchEngine searchEngine = BrowserSettings.getInstance()
- .getSearchEngine();
+ @Override
+ protected void setSearchMode(boolean voiceSearchEnabled) {
boolean showvoicebutton = voiceSearchEnabled &&
- (searchEngine != null && searchEngine.supportsVoiceSearch());
+ mUiController.supportsVoiceSearch();
mVoiceSearch.setVisibility(showvoicebutton ? View.VISIBLE :
View.GONE);
mGoButton.setVisibility(voiceSearchEnabled ? View.GONE :
@@ -510,45 +299,14 @@
}
@Override
- /* package */ void setDisplayTitle(String title) {
- if (!isEditingUrl()) {
- mUrlInput.setText(title, false);
- }
- }
-
- // UrlInput text watcher
-
- @Override
- public void onTextChanged(String newText) {
- if (mUrlInput.hasFocus()) {
- // check if input field is empty and adjust voice search state
- updateSearchMode(true);
- // clear voice mode when user types
- setInVoiceMode(false, null);
- }
- }
-
- // voicesearch
-
- @Override
- public void setInVoiceMode(boolean voicemode) {
- setInVoiceMode(voicemode, null);
- }
-
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
- mInVoiceMode = voicemode;
- mUrlInput.setVoiceResults(voiceResults);
+ super.setInVoiceMode(voicemode, voiceResults);
if (voicemode) {
mUrlIcon.setImageDrawable(mSearchButton.getDrawable());
}
}
@Override
- void setIncognitoMode(boolean incognito) {
- mUrlInput.setIncognitoMode(incognito);
- }
-
- @Override
public View focusSearch(View focused, int dir) {
if (FOCUS_DOWN == dir && hasFocus()) {
return getCurrentWebView();
@@ -556,74 +314,4 @@
return super.focusSearch(focused, dir);
}
- void clearCompletions() {
- mUrlInput.setSuggestedText(null);
- }
-
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent evt) {
- if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- // catch back key in order to do slightly more cleanup than usual
- mUrlInput.clearFocus();
- return true;
- }
- return super.dispatchKeyEventPreIme(evt);
- }
-
- private WebView getCurrentWebView() {
- Tab t = mUi.getActiveTab();
- if (t != null) {
- return t.getWebView();
- } else {
- return null;
- }
- }
-
- void registerDropdownChangeListener(DropdownChangeListener d) {
- mUrlInput.registerDropdownChangeListener(d);
- }
-
- private void hideNavButtons() {
- int awidth = mNavButtons.getMeasuredWidth();
- Animator anim1 = ObjectAnimator.ofFloat(mNavButtons, "translationX", 0, - awidth);
- Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", mUrlContainer.getLeft(),
- mUrlContainer.getPaddingLeft());
- Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, "alpha", 1f, 0f);
- AnimatorSet combo = new AnimatorSet();
- combo.playTogether(anim1, anim2, anim3);
- combo.addListener(new AnimatorListener() {
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mNavButtons.setVisibility(View.GONE);
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- }
- });
- combo.setDuration(150);
- combo.start();
- }
-
- private void showNavButtons() {
- int awidth = mNavButtons.getMeasuredWidth();
- Animator anim1 = ObjectAnimator.ofFloat(mNavButtons, "translationX", -awidth, 0);
- Animator anim2 = ObjectAnimator.ofInt(mUrlContainer, "left", 0, awidth);
- Animator anim3 = ObjectAnimator.ofFloat(mNavButtons, "alpha", 0f, 1f);
- AnimatorSet combo = new AnimatorSet();
- combo.playTogether(anim1, anim2, anim3);
- mNavButtons.setVisibility(View.VISIBLE);
- combo.setDuration(150);
- combo.start();
- }
-
}
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 368c829..a6356a3 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -43,6 +43,8 @@
public boolean onBackKey();
+ public boolean onMenuKey();
+
public boolean needsRestoreAllTabs();
public void addTab(Tab tab);
@@ -79,13 +81,14 @@
public void hideComboView();
- public void showCustomView(View view, CustomViewCallback callback);
+ public void showCustomView(View view, int requestedOrientation,
+ CustomViewCallback callback);
public void onHideCustomView();
public boolean isCustomViewShowing();
- public void showVoiceTitleBar(String title);
+ public void showVoiceTitleBar(String title, List<String> results);
public void revertVoiceTitleBar(Tab tab);
@@ -132,4 +135,6 @@
void showAutoLogin(Tab tab);
void hideAutoLogin(Tab tab);
+
+ void setFullscreen(boolean enabled);
}
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index 65fa5f8..4fc37af 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -44,7 +44,12 @@
Tab openIncognitoTab();
- boolean switchToTab(int tabIndex);
+ Tab openTab(String url, boolean incognito, boolean setActive,
+ boolean useCurrent);
+
+ void setActiveTab(Tab tab);
+
+ boolean switchToTab(Tab tab);
void closeCurrentTab();
@@ -56,10 +61,10 @@
void bookmarksOrHistoryPicker(boolean openHistory);
- void startSearch(String url);
-
void startVoiceSearch();
+ boolean supportsVoiceSearch();
+
void showVoiceSearchResults(String title);
void editUrl();
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index b23dc7d..02a080f 100644
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -22,7 +22,9 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.database.Cursor;
import android.net.Uri;
+import android.os.AsyncTask;
import android.util.Log;
import android.webkit.WebView;
@@ -35,6 +37,9 @@
*/
public class UrlHandler {
+ static final String RLZ_PROVIDER = "com.google.android.partnersetup.rlzappprovider";
+ static final Uri RLZ_PROVIDER_URI = Uri.parse("content://" + RLZ_PROVIDER + "/");
+
// Use in overrideUrlLoading
/* package */ final static String SCHEME_WTAI = "wtai://wp/";
/* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
@@ -44,6 +49,9 @@
Controller mController;
Activity mActivity;
+ private Boolean mIsProviderPresent = null;
+ private Uri mRlzUri = null;
+
public UrlHandler(Controller controller) {
mController = controller;
mActivity = mController.getActivity();
@@ -92,6 +100,20 @@
return false;
}
+ // If this is a Google search, attempt to add an RLZ string
+ // (if one isn't already present).
+ if (rlzProviderPresent()) {
+ Uri siteUri = Uri.parse(url);
+ if (needsRlzString(siteUri)) {
+ // Need to look up the RLZ info from a database, so do it in an
+ // AsyncTask. Although we are not overriding the URL load synchronously,
+ // we guarantee that we will handle this URL load after the task executes,
+ // so it's safe to just return true to WebCore now to stop its own loading.
+ new RLZTask(tab, siteUri, view).execute();
+ return true;
+ }
+ }
+
if (startActivityForUrl(url)) {
return true;
}
@@ -192,11 +214,120 @@
// depressed by opening in a new tab
boolean handleMenuClick(Tab tab, String url) {
if (mController.isMenuDown()) {
- mController.openTab(tab, url, false);
+ mController.openTab(url,
+ (tab != null) && tab.isPrivateBrowsingEnabled(),
+ !BrowserSettings.getInstance().openInBackground(), true);
mActivity.closeOptionsMenu();
return true;
}
return false;
}
+
+ // TODO: Move this class into Tab, where it can be properly stopped upon
+ // closure of the tab
+ private class RLZTask extends AsyncTask<Void, Void, String> {
+ private Tab mTab;
+ private Uri mSiteUri;
+ private WebView mWebView;
+
+ public RLZTask(Tab tab, Uri uri, WebView webView) {
+ mTab = tab;
+ mSiteUri = uri;
+ mWebView = webView;
+ }
+
+ protected String doInBackground(Void... unused) {
+ String result = mSiteUri.toString();
+ Cursor cur = null;
+ try {
+ cur = mActivity.getContentResolver()
+ .query(getRlzUri(), null, null, null, null);
+ if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
+ result = mSiteUri.buildUpon()
+ .appendQueryParameter("rlz", cur.getString(0))
+ .build().toString();
+ }
+ } finally {
+ if (cur != null) {
+ cur.close();
+ }
+ }
+ return result;
+ }
+
+ protected void onPostExecute(String result) {
+ // Make sure the Tab was not closed while handling the task
+ if (mController.getTabControl().getTabPosition(mTab) != -1) {
+ // If the Activity Manager is not invoked, load the URL directly
+ if (!startActivityForUrl(result)) {
+ if (!handleMenuClick(mTab, result)) {
+ mController.loadUrl(mWebView, result);
+ }
+ }
+ }
+ }
+ }
+
+ // Determine whether the RLZ provider is present on the system.
+ private boolean rlzProviderPresent() {
+ if (mIsProviderPresent == null) {
+ PackageManager pm = mActivity.getPackageManager();
+ mIsProviderPresent = pm.resolveContentProvider(RLZ_PROVIDER, 0) != null;
+ }
+ return mIsProviderPresent;
+ }
+
+ // Retrieve the RLZ access point string and cache the URI used to
+ // retrieve RLZ values.
+ private Uri getRlzUri() {
+ if (mRlzUri == null) {
+ String ap = mActivity.getResources()
+ .getString(R.string.rlz_access_point);
+ mRlzUri = Uri.withAppendedPath(RLZ_PROVIDER_URI, ap);
+ }
+ return mRlzUri;
+ }
+
+ // Determine if this URI appears to be for a Google search
+ // and does not have an RLZ parameter.
+ // Taken largely from Chrome source, src/chrome/browser/google_url_tracker.cc
+ private static boolean needsRlzString(Uri uri) {
+ String scheme = uri.getScheme();
+ if (("http".equals(scheme) || "https".equals(scheme)) &&
+ (uri.getQueryParameter("q") != null) &&
+ (uri.getQueryParameter("rlz") == null)) {
+ String host = uri.getHost();
+ if (host == null) {
+ return false;
+ }
+ String[] hostComponents = host.split("\\.");
+
+ if (hostComponents.length < 2) {
+ return false;
+ }
+ int googleComponent = hostComponents.length - 2;
+ String component = hostComponents[googleComponent];
+ if (!"google".equals(component)) {
+ if (hostComponents.length < 3 ||
+ (!"co".equals(component) && !"com".equals(component))) {
+ return false;
+ }
+ googleComponent = hostComponents.length - 3;
+ if (!"google".equals(hostComponents[googleComponent])) {
+ return false;
+ }
+ }
+
+ // Google corp network handling.
+ if (googleComponent > 0 && "corp".equals(
+ hostComponents[googleComponent - 1])) {
+ return false;
+ }
+
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 9c5d338..7545e6a 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -175,7 +175,7 @@
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (BrowserSettings.getInstance().useInstant() &&
+ if (BrowserSettings.getInstance().useInstantSearch() &&
(actionId == EditorInfo.IME_ACTION_NEXT)) {
// When instant is turned on AND the user chooses to complete
// using the tab key, then use the completion rather than the
@@ -298,11 +298,11 @@
}
/*
- * no-op to prevent scrolling of webview when embedded titlebar is edited
+ * no-op to prevent scrolling of webview when embedded titlebar
+ * gets edited
*/
@Override
public boolean requestRectangleOnScreen(Rect rect, boolean immediate) {
return false;
}
-
}
diff --git a/src/com/android/browser/UrlUtils.java b/src/com/android/browser/UrlUtils.java
index 8c789db..ccf9710 100644
--- a/src/com/android/browser/UrlUtils.java
+++ b/src/com/android/browser/UrlUtils.java
@@ -16,8 +16,6 @@
package com.android.browser;
-import com.android.browser.homepages.HomeProvider;
-
import android.net.Uri;
import android.util.Patterns;
import android.webkit.URLUtil;
@@ -59,7 +57,7 @@
* @return a stripped url like "www.google.com", or the original string if it could
* not be stripped
*/
- /* package */ static String stripUrl(String url) {
+ public static String stripUrl(String url) {
if (url == null) return null;
Matcher m = STRIP_URL_PATTERN.matcher(url);
if (m.matches() && m.groupCount() == 3) {
@@ -159,34 +157,4 @@
return inUrl;
}
- // Determine if this URI appears to be a Google property
- /* package */ static boolean isGoogleUri(Uri uri) {
- String scheme = uri.getScheme();
- if (!"http".equals(scheme) && !"https".equals(scheme)) {
- return false;
- }
-
- String host = uri.getHost();
- if (host == null) {
- return false;
- }
- String[] hostComponents = host.split("\\.");
- if (hostComponents.length < 2) {
- return false;
- }
-
- int googleComponent = hostComponents.length - 2;
- String component = hostComponents[googleComponent];
- if (!"google".equals(component)) {
- if (hostComponents.length < 3 ||
- (!"co".equals(component) && !"com".equals(component))) {
- return false;
- }
- googleComponent = hostComponents.length - 3;
- if (!"google".equals(hostComponents[googleComponent])) {
- return false;
- }
- }
- return true;
- }
}
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index 6b44207..018af99 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -16,8 +16,6 @@
package com.android.browser;
-import com.android.browser.IntentHandler.UrlData;
-
import android.app.Activity;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -31,6 +29,8 @@
import android.webkit.WebChromeClient;
import android.webkit.WebView;
+import java.util.List;
+
/**
* WebView aspect of the controller
*/
@@ -72,7 +72,8 @@
void onDownloadStart(Tab tab, String url, String useragent, String contentDisposition,
String mimeType, long contentLength);
- void showCustomView(Tab tab, View view, WebChromeClient.CustomViewCallback callback);
+ void showCustomView(Tab tab, View view, int requestedOrientation,
+ WebChromeClient.CustomViewCallback callback);
void hideCustomView();
@@ -85,7 +86,7 @@
void onUserCanceledSsl(Tab tab);
- void activateVoiceSearchMode(String title);
+ void activateVoiceSearchMode(String title, List<String> results);
void revertVoiceSearchMode(Tab tab);
@@ -101,10 +102,13 @@
void dismissSubWindow(Tab tab);
- Tab openTabAndShow(Tab parent, UrlData urlData, boolean closeOnExit,
- String appId);
+ Tab openTab(String url, boolean incognito, boolean setActive,
+ boolean useCurrent);
- boolean switchToTab(int tabindex);
+ Tab openTab(String url, Tab parent, boolean setActive,
+ boolean useCurrent);
+
+ boolean switchToTab(Tab tab);
void closeTab(Tab tab);
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 8c34fc9..1530ed3 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -16,26 +16,19 @@
package com.android.browser;
-import com.android.browser.ScrollWebView.ScrollListener;
+import com.android.browser.BrowserWebView.ScrollListener;
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.ObjectAnimator;
import android.app.ActionBar;
import android.app.Activity;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
-import android.view.Menu;
import android.view.View;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.WebView;
-import android.widget.FrameLayout;
import java.util.List;
@@ -50,8 +43,6 @@
private TabBar mTabBar;
private TitleBarXLarge mTitleBar;
- private Animator mTitleBarAnimator;
- private boolean mSkipTitleBarAnimations;
private boolean mUseQuickControls;
private PieControl mPieControl;
@@ -64,7 +55,8 @@
public XLargeUi(Activity browser, UiController controller) {
super(browser, controller);
mHandler = new Handler();
- mTitleBar = new TitleBarXLarge(mActivity, mUiController, this);
+ mTitleBar = new TitleBarXLarge(mActivity, mUiController, this,
+ mContentView);
mTitleBar.setProgress(100);
mTabBar = new TabBar(mActivity, mUiController, this);
mActionBar = mActivity.getActionBar();
@@ -103,16 +95,16 @@
checkTabCount();
mPieControl = new PieControl(mActivity, mUiController, this);
mPieControl.attachToContainer(mContentView);
- Tab tab = getActiveTab();
- if ((tab != null) && (tab.getWebView() != null)) {
- tab.getWebView().setEmbeddedTitleBar(null);
+ WebView web = getWebView();
+ if (web != null) {
+ web.setEmbeddedTitleBar(null);
}
} else {
mActivity.getActionBar().show();
if (mPieControl != null) {
mPieControl.removeFromContainer(mContentView);
}
- WebView web = mTabControl.getCurrentWebView();
+ WebView web = getWebView();
if (web != null) {
web.setEmbeddedTitleBar(mTitleBar);
}
@@ -134,7 +126,7 @@
@Override
public void onResume() {
super.onResume();
- if (!BrowserSettings.getInstance().useInstant()) {
+ if (!BrowserSettings.getInstance().useInstantSearch()) {
mTitleBar.clearCompletions();
}
}
@@ -149,23 +141,14 @@
@Override
public WebView createWebView(boolean privateBrowsing) {
// Create a new WebView
- ScrollWebView w = new ScrollWebView(mActivity, null,
- android.R.attr.webViewStyle, privateBrowsing);
- initWebViewSettings(w);
+ BrowserWebView w = (BrowserWebView) super.createWebView(privateBrowsing);
w.setScrollListener(this);
- boolean supportsMultiTouch = mActivity.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH);
- w.getSettings().setDisplayZoomControls(!supportsMultiTouch);
- w.setExpandedTileBounds(true); // smoother scrolling
return w;
}
@Override
public WebView createSubWebView(boolean privateBrowsing) {
- ScrollWebView web = (ScrollWebView) createWebView(privateBrowsing);
- // no scroll listener for subview
- web.setScrollListener(null);
- return web;
+ return super.createWebView(privateBrowsing);
}
@Override
@@ -174,7 +157,7 @@
}
void stopWebViewScrolling() {
- ScrollWebView web = (ScrollWebView) mUiController.getCurrentWebView();
+ BrowserWebView web = (BrowserWebView) mUiController.getCurrentWebView();
if (web != null) {
web.stopScroll();
}
@@ -188,31 +171,10 @@
mTabBar.onProgress(tab, progress);
if (tab.inForeground()) {
mTitleBar.setProgress(progress);
- if (progress == 100) {
- if (!mTitleBar.isEditingUrl() && !mTitleBar.inAutoLogin()) {
- hideTitleBar();
- if (mUseQuickControls) {
- mTitleBar.setShowProgressOnly(false);
- }
- }
- } else {
- if (!isTitleBarShowing()) {
- if (mUseQuickControls && !mTitleBar.isEditingUrl()) {
- mTitleBar.setShowProgressOnly(true);
- setTitleGravity(Gravity.TOP);
- }
- showTitleBar();
- }
- }
}
}
@Override
- public boolean needsRestoreAllTabs() {
- return true;
- }
-
- @Override
public void addTab(Tab tab) {
mTabBar.onNewTab(tab);
}
@@ -223,9 +185,8 @@
@Override
public void setActiveTab(final Tab tab) {
- cancelTitleBarAnimation(true);
- mSkipTitleBarAnimations = true;
- stopEditingUrl();
+ mTitleBar.cancelTitleBarAnimation(true);
+ mTitleBar.setSkipTitleBarAnimations(true);
if (mUseQuickControls) {
if (mActiveTab != null) {
captureTab(mActiveTab);
@@ -233,12 +194,12 @@
}
super.setActiveTab(tab, true);
setActiveTab(tab, true);
- mSkipTitleBarAnimations = false;
+ mTitleBar.setSkipTitleBarAnimations(false);
}
@Override
void setActiveTab(Tab tab, boolean needsAttaching) {
- ScrollWebView view = (ScrollWebView) tab.getWebView();
+ BrowserWebView view = (BrowserWebView) tab.getWebView();
// TabControl.setCurrentTab has been called before this,
// so the tab is guaranteed to have a webview
if (view == null) {
@@ -259,7 +220,7 @@
}
mTabBar.onSetActiveTab(tab);
if (tab.isInVoiceSearchMode()) {
- showVoiceTitleBar(tab.getVoiceDisplayTitle());
+ showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults());
} else {
revertVoiceTitleBar(tab);
}
@@ -267,15 +228,6 @@
tab.getTopWindow().requestFocus();
}
- public void captureTab(final Tab tab) {
- Bitmap sshot = Controller.createScreenshot(tab,
- (int) mActivity.getResources()
- .getDimension(R.dimen.qc_thumb_width),
- (int) mActivity.getResources()
- .getDimension(R.dimen.qc_thumb_height));
- tab.setScreenshot(sshot);
- }
-
@Override
public void updateTabs(List<Tab> tabs) {
mTabBar.updateTabs(tabs);
@@ -284,11 +236,11 @@
@Override
public void removeTab(Tab tab) {
- cancelTitleBarAnimation(true);
- mSkipTitleBarAnimations = true;
+ mTitleBar.cancelTitleBarAnimation(true);
+ mTitleBar.setSkipTitleBarAnimations(true);
super.removeTab(tab);
mTabBar.onRemoveTab(tab);
- mSkipTitleBarAnimations = false;
+ mTitleBar.setSkipTitleBarAnimations(false);
}
protected void onRemoveTabCompleted(Tab tab) {
@@ -304,17 +256,10 @@
@Override
public void editUrl(boolean clearInput) {
- if (mUiController.isInCustomActionMode()) {
- mUiController.endActionMode();
+ if (mUseQuickControls) {
+ getTitleBar().setShowProgressOnly(false);
}
- showTitleBar();
- mTitleBar.startEditingUrl(clearInput);
- }
-
- void showTitleBarAndEdit() {
- mTitleBar.setShowProgressOnly(false);
- showTitleBar();
- mTitleBar.startEditingUrl(false);
+ super.editUrl(clearInput);
}
void stopEditingUrl() {
@@ -324,24 +269,7 @@
@Override
protected void showTitleBar() {
if (canShowTitleBar()) {
- if (mUseQuickControls) {
- mContentView.addView(mTitleBar);
- } else {
- if (!mSkipTitleBarAnimations) {
- cancelTitleBarAnimation(false);
- int visibleHeight = getVisibleTitleHeight();
- float startPos = (-mTitleBar.getEmbeddedHeight() + visibleHeight);
- if (mTitleBar.getTranslationY() != 0) {
- startPos = Math.max(startPos, mTitleBar.getTranslationY());
- }
- mTitleBarAnimator = ObjectAnimator.ofFloat(mTitleBar,
- "translationY",
- startPos, 0);
- mTitleBarAnimator.start();
- }
- setTitleGravity(Gravity.TOP);
- }
- super.showTitleBar();
+ mTitleBar.show();
mTabBar.onShowTitleBar();
}
}
@@ -350,66 +278,10 @@
protected void hideTitleBar() {
if (isTitleBarShowing()) {
mTabBar.onHideTitleBar();
- if (mUseQuickControls) {
- mContentView.removeView(mTitleBar);
- } else {
- if (!mSkipTitleBarAnimations) {
- cancelTitleBarAnimation(false);
- int visibleHeight = getVisibleTitleHeight();
- mTitleBarAnimator = ObjectAnimator.ofFloat(mTitleBar,
- "translationY", mTitleBar.getTranslationY(),
- (-mTitleBar.getEmbeddedHeight() + visibleHeight));
- mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
- mTitleBarAnimator.start();
- } else {
- setTitleGravity(Gravity.NO_GRAVITY);
- }
- }
- super.hideTitleBar();
+ mTitleBar.hide();
}
}
- private void cancelTitleBarAnimation(boolean reset) {
- if (mTitleBarAnimator != null) {
- mTitleBarAnimator.cancel();
- mTitleBarAnimator = null;
- }
- if (reset) {
- mTitleBar.setTranslationY(0);
- }
- }
-
- private int getVisibleTitleHeight() {
- WebView webview = mActiveTab != null ? mActiveTab.getWebView() : null;
- return webview != null ? webview.getVisibleTitleHeight() : 0;
- }
-
- private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
-
- boolean mWasCanceled;
- @Override
- public void onAnimationStart(Animator animation) {
- mWasCanceled = false;
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mWasCanceled) {
- mTitleBar.setTranslationY(0);
- }
- setTitleGravity(Gravity.NO_GRAVITY);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mWasCanceled = true;
- }
- };
-
public boolean isEditingUrl() {
return mTitleBar.isEditingUrl();
}
@@ -421,12 +293,7 @@
@Override
protected void setTitleGravity(int gravity) {
- if (mUseQuickControls) {
- FrameLayout.LayoutParams lp =
- (FrameLayout.LayoutParams) mTitleBar.getLayoutParams();
- lp.gravity = gravity;
- mTitleBar.setLayoutParams(lp);
- } else {
+ if (!mUseQuickControls) {
super.setTitleGravity(gravity);
}
}
@@ -460,18 +327,6 @@
}
@Override
- protected void updateAutoLogin(Tab tab, boolean animate) {
- mTitleBar.updateAutoLogin(tab, animate);
- }
-
- protected void refreshWebView() {
- Tab tab = getActiveTab();
- if ((tab != null) && (tab.getWebView() != null)) {
- tab.getWebView().invalidate();
- }
- }
-
- @Override
public void setUrlTitle(Tab tab) {
super.setUrlTitle(tab);
mTabBar.onUrlAndTitle(tab, tab.getUrl(), tab.getTitle());
@@ -485,11 +340,7 @@
}
@Override
- public void showVoiceTitleBar(String title) {
- List<String> vsresults = null;
- if (getActiveTab() != null) {
- vsresults = getActiveTab().getVoiceSearchResults();
- }
+ public void showVoiceTitleBar(String title, List<String> vsresults) {
mTitleBar.setInVoiceMode(true, vsresults);
mTitleBar.setDisplayTitle(title);
}
@@ -502,8 +353,9 @@
}
@Override
- public void showCustomView(View view, CustomViewCallback callback) {
- super.showCustomView(view, callback);
+ public void showCustomView(View view, int requestedOrientation,
+ CustomViewCallback callback) {
+ super.showCustomView(view, requestedOrientation, callback);
mActivity.getActionBar().hide();
}
@@ -549,19 +401,4 @@
return mTabBar;
}
- @Override
- public void registerDropdownChangeListener(DropdownChangeListener d) {
- mTitleBar.registerDropdownChangeListener(d);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- if (mUseQuickControls) {
- mPieControl.onMenuOpened(menu);
- return false;
- } else {
- return true;
- }
- }
-
}
diff --git a/src/com/android/browser/addbookmark/FolderSpinnerAdapter.java b/src/com/android/browser/addbookmark/FolderSpinnerAdapter.java
index 261aa62..67563c0 100644
--- a/src/com/android/browser/addbookmark/FolderSpinnerAdapter.java
+++ b/src/com/android/browser/addbookmark/FolderSpinnerAdapter.java
@@ -19,33 +19,37 @@
import com.android.browser.R;
import android.content.Context;
-import android.content.res.Resources;
-import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Adapter;
-import android.widget.SpinnerAdapter;
+import android.widget.BaseAdapter;
import android.widget.TextView;
/**
* SpinnerAdapter used in the AddBookmarkPage to select where to save a
* bookmark/folder.
*/
-public class FolderSpinnerAdapter implements SpinnerAdapter {
- private boolean mIncludeHomeScreen;
- private boolean mIncludesRecentFolder;
- private long mRecentFolderId;
- private String mRecentFolderName;
+public class FolderSpinnerAdapter extends BaseAdapter {
public static final int HOME_SCREEN = 0;
public static final int ROOT_FOLDER = 1;
public static final int OTHER_FOLDER = 2;
public static final int RECENT_FOLDER = 3;
- public FolderSpinnerAdapter(boolean includeHomeScreen) {
+ private boolean mIncludeHomeScreen;
+ private boolean mIncludesRecentFolder;
+ private long mRecentFolderId;
+ private String mRecentFolderName;
+ private LayoutInflater mInflater;
+ private Context mContext;
+ private String mOtherFolderDisplayText;
+
+ public FolderSpinnerAdapter(Context context, boolean includeHomeScreen) {
mIncludeHomeScreen = includeHomeScreen;
+ mContext = context;
+ mInflater = LayoutInflater.from(mContext);
}
public void addRecentFolder(long folderId, String folderName) {
@@ -56,8 +60,7 @@
public long recentFolderId() { return mRecentFolderId; }
- @Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ private void bindView(int position, View view, boolean isDropDown) {
int labelResource;
int drawableResource;
if (!mIncludeHomeScreen) {
@@ -84,26 +87,39 @@
// assert
break;
}
- Context context = parent.getContext();
- LayoutInflater factory = LayoutInflater.from(context);
- TextView textView = (TextView) factory.inflate(R.layout.add_to_option, null);
+ TextView textView = (TextView) view;
if (position == RECENT_FOLDER) {
textView.setText(mRecentFolderName);
+ } else if (position == OTHER_FOLDER && !isDropDown
+ && mOtherFolderDisplayText != null) {
+ textView.setText(mOtherFolderDisplayText);
} else {
textView.setText(labelResource);
}
- Drawable drawable = context.getResources().getDrawable(drawableResource);
+ textView.setGravity(Gravity.CENTER_VERTICAL);
+ Drawable drawable = mContext.getResources().getDrawable(drawableResource);
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null,
null, null);
- return textView;
}
@Override
- public void registerDataSetObserver(DataSetObserver observer) {
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(
+ android.R.layout.simple_spinner_dropdown_item, parent, false);
+ }
+ bindView(position, convertView, true);
+ return convertView;
}
@Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(android.R.layout.simple_spinner_item,
+ parent, false);
+ }
+ bindView(position, convertView, false);
+ return convertView;
}
@Override
@@ -133,24 +149,9 @@
return true;
}
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return getDropDownView(position, convertView, parent);
+ public void setOtherFolderDisplayText(String parentTitle) {
+ mOtherFolderDisplayText = parentTitle;
+ notifyDataSetChanged();
}
- @Override
- public int getItemViewType(int position) {
- // Never want to recycle views
- return Adapter.IGNORE_ITEM_VIEW_TYPE;
- }
-
- @Override
- public int getViewTypeCount() {
- return 1;
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
}
diff --git a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
index e51a629..50ba758 100644
--- a/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
+++ b/src/com/android/browser/autocomplete/SuggestiveAutoCompleteTextView.java
@@ -752,7 +752,7 @@
}
private void updateText(SuggestionsAdapter adapter) {
- if (!BrowserSettings.getInstance().useInstant()) {
+ if (!BrowserSettings.getInstance().useInstantSearch()) {
return;
}
diff --git a/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
new file mode 100644
index 0000000..99bd687
--- /dev/null
+++ b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 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.preferences;
+
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.view.View;
+
+public class AccessibilityPreferencesFragment extends PreferenceFragment
+ implements Preference.OnPreferenceChangeListener {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.accessibility_preferences);
+
+ Preference e = findPreference(PreferenceKeys.PREF_TEXT_SIZE);
+ e.setOnPreferenceChangeListener(this);
+ e.setSummary(getVisualTextSizeName(
+ getPreferenceScreen().getSharedPreferences()
+ .getString(PreferenceKeys.PREF_TEXT_SIZE, null)) );
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ getListView().setItemsCanFocus(true);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (getActivity() == null) {
+ // We aren't attached, so don't accept preferences changes from the
+ // invisible UI.
+ return false;
+ }
+
+ if (pref.getKey().equals(PreferenceKeys.PREF_TEXT_SIZE)) {
+ pref.setSummary(getVisualTextSizeName((String) objValue));
+ return true;
+ }
+ return false;
+ }
+
+ private CharSequence getVisualTextSizeName(String enumName) {
+ Resources res = getActivity().getResources();
+ CharSequence[] visualNames = res.getTextArray(R.array.pref_text_size_choices);
+ CharSequence[] enumNames = res.getTextArray(R.array.pref_text_size_values);
+
+ // Sanity check
+ if (visualNames.length != enumNames.length) {
+ return "";
+ }
+
+ int length = enumNames.length;
+ for (int i = 0; i < length; i++) {
+ if (enumNames[i].equals(enumName)) {
+ return visualNames[i];
+ }
+ }
+
+ return "";
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
index e2e45f5..2cc504e 100644
--- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -17,7 +17,7 @@
package com.android.browser.preferences;
import com.android.browser.BrowserActivity;
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
import com.android.browser.R;
import android.content.Intent;
@@ -46,28 +46,22 @@
addPreferencesFromResource(R.xml.advanced_preferences);
PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
- BrowserSettings.PREF_WEBSITE_SETTINGS);
+ PreferenceKeys.PREF_WEBSITE_SETTINGS);
websiteSettings.setFragment(WebsiteSettingsFragment.class.getName());
- Preference e = findPreference(BrowserSettings.PREF_TEXT_SIZE);
- e.setOnPreferenceChangeListener(this);
- e.setSummary(getVisualTextSizeName(
- getPreferenceScreen().getSharedPreferences()
- .getString(BrowserSettings.PREF_TEXT_SIZE, null)) );
-
- e = findPreference(BrowserSettings.PREF_DEFAULT_ZOOM);
+ Preference e = findPreference(PreferenceKeys.PREF_DEFAULT_ZOOM);
e.setOnPreferenceChangeListener(this);
e.setSummary(getVisualDefaultZoomName(
getPreferenceScreen().getSharedPreferences()
- .getString(BrowserSettings.PREF_DEFAULT_ZOOM, null)) );
+ .getString(PreferenceKeys.PREF_DEFAULT_ZOOM, null)) );
- e = findPreference(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING);
+ e = findPreference(PreferenceKeys.PREF_DEFAULT_TEXT_ENCODING);
e.setOnPreferenceChangeListener(this);
- e = findPreference(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS);
+ e = findPreference(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES);
e.setOnPreferenceChangeListener(this);
- e = findPreference(BrowserSettings.PREF_PLUGIN_STATE);
+ e = findPreference(PreferenceKeys.PREF_PLUGIN_STATE);
e.setOnPreferenceChangeListener(this);
updatePluginSummary((ListPreference) e);
}
@@ -85,7 +79,7 @@
public void onResume() {
super.onResume();
final PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
- BrowserSettings.PREF_WEBSITE_SETTINGS);
+ PreferenceKeys.PREF_WEBSITE_SETTINGS);
websiteSettings.setEnabled(false);
WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
@Override
@@ -114,23 +108,20 @@
return false;
}
- if (pref.getKey().equals(BrowserSettings.PREF_TEXT_SIZE)) {
- pref.setSummary(getVisualTextSizeName((String) objValue));
- return true;
- } else if (pref.getKey().equals(BrowserSettings.PREF_DEFAULT_ZOOM)) {
+ if (pref.getKey().equals(PreferenceKeys.PREF_DEFAULT_ZOOM)) {
pref.setSummary(getVisualDefaultZoomName((String) objValue));
return true;
- } else if (pref.getKey().equals(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING)) {
+ } else if (pref.getKey().equals(PreferenceKeys.PREF_DEFAULT_TEXT_ENCODING)) {
pref.setSummary((String) objValue);
return true;
- } else if (pref.getKey().equals(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS)) {
+ } else if (pref.getKey().equals(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES)) {
Boolean value = (Boolean) objValue;
if (value.booleanValue() == true) {
startActivity(new Intent(BrowserActivity.ACTION_RESTART, null,
getActivity(), BrowserActivity.class));
return true;
}
- } else if (pref.getKey().equals(BrowserSettings.PREF_PLUGIN_STATE)) {
+ } else if (pref.getKey().equals(PreferenceKeys.PREF_PLUGIN_STATE)) {
ListPreference lp = (ListPreference) pref;
lp.setValue((String) objValue);
updatePluginSummary(lp);
@@ -139,26 +130,6 @@
return false;
}
- private CharSequence getVisualTextSizeName(String enumName) {
- Resources res = getActivity().getResources();
- CharSequence[] visualNames = res.getTextArray(R.array.pref_text_size_choices);
- CharSequence[] enumNames = res.getTextArray(R.array.pref_text_size_values);
-
- // Sanity check
- if (visualNames.length != enumNames.length) {
- return "";
- }
-
- int length = enumNames.length;
- for (int i = 0; i < length; i++) {
- if (enumNames[i].equals(enumName)) {
- return visualNames[i];
- }
- }
-
- return "";
- }
-
private CharSequence getVisualDefaultZoomName(String enumName) {
Resources res = getActivity().getResources();
CharSequence[] visualNames = res.getTextArray(R.array.pref_default_zoom_choices);
diff --git a/src/com/android/browser/preferences/DebugPreferencesFragment.java b/src/com/android/browser/preferences/DebugPreferencesFragment.java
index 0a82371..984c12a 100644
--- a/src/com/android/browser/preferences/DebugPreferencesFragment.java
+++ b/src/com/android/browser/preferences/DebugPreferencesFragment.java
@@ -18,21 +18,14 @@
import com.android.browser.BrowserActivity;
import com.android.browser.BrowserSettings;
-import com.android.browser.Controller;
+import com.android.browser.PreferenceKeys;
import com.android.browser.R;
-import android.content.Context;
import android.content.Intent;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.PreferenceActivity.Header;
import android.preference.PreferenceFragment;
-import android.preference.PreferenceManager.OnActivityResultListener;
-
-import java.io.IOException;
-import java.io.Serializable;
public class DebugPreferencesFragment extends PreferenceFragment
implements OnPreferenceChangeListener {
@@ -43,11 +36,7 @@
// Load the XML preferences file
addPreferencesFromResource(R.xml.debug_preferences);
- if (BrowserSettings.getInstance().showDebugSettings()) {
- addPreferencesFromResource(R.xml.hidden_debug_preferences);
- }
-
- Preference e = findPreference(BrowserSettings.PREF_HARDWARE_ACCEL);
+ Preference e = findPreference(PreferenceKeys.PREF_ENABLE_HARDWARE_ACCEL);
e.setOnPreferenceChangeListener(this);
}
diff --git a/src/com/android/browser/preferences/GeneralPreferencesFragment.java b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
index 0c63ab5..af0fc50 100644
--- a/src/com/android/browser/preferences/GeneralPreferencesFragment.java
+++ b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
@@ -16,45 +16,21 @@
package com.android.browser.preferences;
-import com.android.browser.BrowserBookmarksPage;
-import com.android.browser.BrowserHomepagePreference;
-import com.android.browser.BrowserPreferencesPage;
-import com.android.browser.BrowserSettings;
-import com.android.browser.R;
-import com.android.browser.widget.BookmarkThumbnailWidgetProvider;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
-import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
-import android.provider.BrowserContract;
import android.util.Log;
+import com.android.browser.BrowserHomepagePreference;
+import com.android.browser.BrowserPreferencesPage;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
public class GeneralPreferencesFragment extends PreferenceFragment
- implements OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
+ implements Preference.OnPreferenceChangeListener {
static final String TAG = "PersonalPreferencesFragment";
- static final String PREF_CHROME_SYNC = "sync_with_chrome";
-
- Preference mChromeSync;
- boolean mEnabled;
- SharedPreferences mSharedPrefs;
- Account[] mAccounts;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -62,14 +38,12 @@
// Load the XML preferences file
addPreferencesFromResource(R.xml.general_preferences);
- Preference e = findPreference(BrowserSettings.PREF_HOMEPAGE);
+ Preference e = findPreference(PreferenceKeys.PREF_HOMEPAGE);
e.setOnPreferenceChangeListener(this);
e.setSummary(getPreferenceScreen().getSharedPreferences()
- .getString(BrowserSettings.PREF_HOMEPAGE, null));
+ .getString(PreferenceKeys.PREF_HOMEPAGE, null));
((BrowserHomepagePreference) e).setCurrentPage(
getActivity().getIntent().getStringExtra(BrowserPreferencesPage.CURRENT_PAGE));
- mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
- mSharedPrefs.registerOnSharedPreferenceChangeListener(mListener);
}
@Override
@@ -81,7 +55,7 @@
return false;
}
- if (pref.getKey().equals(BrowserSettings.PREF_HOMEPAGE)) {
+ if (pref.getKey().equals(PreferenceKeys.PREF_HOMEPAGE)) {
pref.setSummary((String) objValue);
return true;
}
@@ -93,171 +67,12 @@
public void onResume() {
super.onResume();
- // Setup the proper state for the sync with chrome item
- mChromeSync = findPreference(PREF_CHROME_SYNC);
refreshUi();
}
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- mSharedPrefs.unregisterOnSharedPreferenceChangeListener(mListener);
- }
-
- OnSharedPreferenceChangeListener mListener
- = new OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(
- SharedPreferences sharedPreferences, String key) {
- if (BrowserBookmarksPage.PREF_ACCOUNT_NAME.equals(key)
- || BrowserBookmarksPage.PREF_ACCOUNT_TYPE.equals(key)) {
- refreshUi();
- BookmarkThumbnailWidgetProvider.refreshWidgets(getActivity(), true);
- }
- }
-
- };
-
- private AccountManagerCallback<Bundle> mCallback =
- new AccountManagerCallback<Bundle>() {
-
- @Override
- public void run(AccountManagerFuture<Bundle> future) {
- try {
- Bundle bundle = future.getResult();
- String name = bundle.getString(AccountManager.KEY_ACCOUNT_NAME);
- String type = bundle.getString(AccountManager.KEY_ACCOUNT_TYPE);
- Account account = new Account(name, type);
- mAccounts = new Account[] { account };
- ImportWizard wizard = ImportWizard.newInstance(mAccounts);
- wizard.show(getFragmentManager(), null);
- } catch (Exception ex) {
- // Canceled or failed to login, doesn't matter to us
- }
- }
- };
-
- OnPreferenceClickListener mAddAccount = new OnPreferenceClickListener() {
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- AccountManager am = AccountManager.get(getActivity());
- am.addAccount("com.google", null, null, null, getActivity(),
- mCallback, null);
- return true;
- }
- };
-
- private class GetAccountsTask extends AsyncTask<Void, Void, String> {
- private Context mContext;
-
- GetAccountsTask(Context ctx) {
- mContext = ctx;
- }
-
- @Override
- protected String doInBackground(Void... unused) {
- AccountManager am = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
- Account[] accounts = am.getAccountsByType("com.google");
- if (accounts == null || accounts.length == 0) {
- // No Google accounts setup, don't offer Chrome sync
- if (mChromeSync != null) {
- mChromeSync.setOnPreferenceClickListener(mAddAccount);
- }
- } else {
- // Google accounts are present.
- mAccounts = accounts;
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
- Bundle args = mChromeSync.getExtras();
- args.putParcelableArray("accounts", accounts);
- mEnabled = BrowserContract.Settings.isSyncEnabled(mContext);
- mChromeSync.setOnPreferenceClickListener(GeneralPreferencesFragment.this);
-
- if (!mEnabled) {
- // Setup a link to the enable wizard
- return mContext.getResources().getString(
- R.string.pref_personal_sync_with_chrome_summary);
- } else {
- // Chrome sync is enabled, setup a link to account switcher
- String accountName = prefs.getString(
- BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- args.putString("curAccount", accountName);
- return accountName;
- }
- }
-
- return null;
- }
-
- @Override
- protected void onPostExecute(String summary) {
- if (summary != null) {
- mChromeSync.setSummary(summary);
- }
- }
- }
-
void refreshUi() {
- new GetAccountsTask(getActivity()).execute();
-
PreferenceScreen autoFillSettings =
- (PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
- autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (mAccounts == null) {
- Log.w(TAG, "NULL accounts!");
- return true;
- }
- DialogFragment frag;
- if (mEnabled) {
- frag = new AccountChooserDialog();
- frag.setArguments(preference.getExtras());
- } else {
- frag = ImportWizard.newInstance(mAccounts);
- }
- frag.show(getFragmentManager(), null);
- return true;
- }
-
- public static class AccountChooserDialog extends DialogFragment
- implements DialogInterface.OnClickListener {
-
- AlertDialog mDialog;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- Bundle args = getArguments();
- Account[] accounts = (Account[]) args.getParcelableArray("accounts");
- String curAccount = args.getString("curAccount");
- int length = accounts.length;
- int curAccountOffset = 0;
- CharSequence[] accountNames = new CharSequence[length];
- for (int i = 0; i < length; i++) {
- String name = accounts[i].name;
- if (name.equals(curAccount)) {
- curAccountOffset = i;
- }
- accountNames[i] = name;
- }
-
- mDialog = new AlertDialog.Builder(getActivity())
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(R.string.account_chooser_dialog_title)
- .setSingleChoiceItems(accountNames, curAccountOffset, this)
- .create();
- return mDialog;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String accountName = mDialog.getListView().getAdapter().getItem(which).toString();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
- prefs.edit().putString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, accountName).apply();
- dismiss();
- }
+ (PreferenceScreen)findPreference(PreferenceKeys.PREF_AUTOFILL_PROFILE);
+ autoFillSettings.setDependency(PreferenceKeys.PREF_AUTOFILL_ENABLED);
}
}
diff --git a/src/com/android/browser/preferences/ImportWizard.java b/src/com/android/browser/preferences/ImportWizard.java
deleted file mode 100644
index 7105f4d..0000000
--- a/src/com/android/browser/preferences/ImportWizard.java
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2011 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.preferences;
-
-import com.android.browser.BrowserBookmarksPage;
-import com.android.browser.R;
-import com.android.browser.view.EventRedirectingFrameLayout;
-
-import android.accounts.Account;
-import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnKeyListener;
-import android.content.DialogInterface.OnShowListener;
-import android.content.OperationApplicationException;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.preference.PreferenceManager;
-import android.provider.BrowserContract;
-import android.provider.BrowserContract.Bookmarks;
-import android.provider.BrowserContract.ChromeSyncColumns;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-
-public class ImportWizard extends DialogFragment implements OnClickListener,
- OnItemClickListener {
-
- static final String TAG = "BookmarkImportWizard";
-
- static final int PAGE_IMPORT_OR_DELETE = 0;
- static final int PAGE_SELECT_ACCOUNT = 1;
- static final int PAGE_CONFIRMATION = 2;
-
- static final String STATE_CURRENT_PAGE = "wizard.current_page";
- static final String STATE_IMPORT_OR_DELETE = "wizard.import_or_delete";
- static final String STATE_SELECTED_ACCOUNT = "wizard.selected_account";
-
- static final String ARG_ACCOUNTS = "accounts";
-
- AlertDialog mDialog;
- EventRedirectingFrameLayout mPages;
- int mCurrentPage;
- Button mPositiveButton, mNegativeButton;
- ListView mImportOrDelete, mSelectAccount;
- Account[] mAccounts;
- TextView mSelectAccountDescription, mConfirmation;
-
- static ImportWizard newInstance(Account[] accounts) {
- ImportWizard wizard = new ImportWizard();
- Bundle args = new Bundle();
- args.putParcelableArray(ARG_ACCOUNTS, accounts);
- wizard.setArguments(args);
- return wizard;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mAccounts = (Account[]) getArguments().getParcelableArray(ARG_ACCOUNTS);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- mDialog = new AlertDialog.Builder(getActivity())
- .setTitle(R.string.import_bookmarks_dialog_title)
- .setView(createView(savedInstanceState))
- .setPositiveButton("?", null) // This is just a placeholder
- .setNegativeButton("?", null) // Ditto
- .setOnKeyListener(new OnKeyListener() {
- @Override
- public boolean onKey(DialogInterface arg0, int arg1, KeyEvent key) {
- if (key.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- if (key.getAction() == KeyEvent.ACTION_UP
- && !key.isCanceled()) {
- mNegativeButton.performClick();
- }
- return true;
- }
- return false;
- }
- })
- .create();
- mDialog.setOnShowListener(new OnShowListener() {
- @Override
- public void onShow(DialogInterface dialog) {
- mPositiveButton = mDialog.getButton(AlertDialog.BUTTON_POSITIVE);
- mNegativeButton = mDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
- mPositiveButton.setOnClickListener(ImportWizard.this);
- mNegativeButton.setOnClickListener(ImportWizard.this);
- setupAnimations();
- updateNavigation();
- }
- });
- return mDialog;
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(STATE_CURRENT_PAGE, mCurrentPage);
- outState.putInt(STATE_IMPORT_OR_DELETE, mImportOrDelete.getCheckedItemPosition());
- outState.putInt(STATE_SELECTED_ACCOUNT, mSelectAccount.getCheckedItemPosition());
- }
-
- public View createView(Bundle savedInstanceState) {
- LayoutInflater inflater = LayoutInflater.from(getActivity());
- View root = inflater.inflate(R.layout.bookmark_sync_wizard, null);
- mPages = (EventRedirectingFrameLayout) root.findViewById(R.id.pages);
- if (mPages.getChildCount() < 1) {
- throw new IllegalStateException("no pages in wizard!");
- }
- if (savedInstanceState != null) {
- mCurrentPage = savedInstanceState.getInt(STATE_CURRENT_PAGE);
- } else {
- mCurrentPage = 0;
- }
- setupPage1(savedInstanceState);
- setupPage2(savedInstanceState);
- setupPage3(savedInstanceState);
- for (int i = 0; i < mPages.getChildCount(); i++) {
- View v = mPages.getChildAt(i);
- if (i <= mCurrentPage) {
- preparePage();
- v.setVisibility(View.VISIBLE);
- } else {
- v.setVisibility(View.GONE);
- }
- }
- mPages.setTargetChild(mCurrentPage);
- return root;
- }
-
- void setupPage1(Bundle savedInstanceState) {
- mImportOrDelete = (ListView) mPages.findViewById(R.id.add_remove_bookmarks);
- // Add an empty header so we get a divider above the list
- mImportOrDelete.addHeaderView(new View(getActivity()));
- Resources res = getActivity().getResources();
- String[] choices = new String[] {
- res.getString(R.string.import_bookmarks_dialog_add),
- res.getString(R.string.import_bookmarks_dialog_remove)
- };
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
- R.layout.bookmark_sync_wizard_item, choices);
- mImportOrDelete.setAdapter(adapter);
- if (savedInstanceState != null) {
- int position = savedInstanceState.getInt(STATE_IMPORT_OR_DELETE);
- if (position == ListView.INVALID_POSITION) {
- mImportOrDelete.clearChoices();
- } else {
- mImportOrDelete.setItemChecked(position, true);
- }
- }
- mImportOrDelete.setOnItemClickListener(this);
- }
-
- void setupPage2(Bundle savedInstanceState) {
- mSelectAccount = (ListView) mPages.findViewById(R.id.select_account);
- mSelectAccountDescription =
- (TextView) mPages.findViewById(R.id.select_account_description);
- // Add an empty header so we get a divider above the list
- mSelectAccount.addHeaderView(new View(getActivity()));
- Resources res = getActivity().getResources();
- String[] accountNames = new String[mAccounts.length];
- for (int i = 0; i < mAccounts.length; i++) {
- accountNames[i] = mAccounts[i].name;
- }
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
- R.layout.bookmark_sync_wizard_item, accountNames);
- mSelectAccount.setAdapter(adapter);
- mSelectAccount.setItemChecked(mSelectAccount.getHeaderViewsCount(), true);
- if (savedInstanceState != null) {
- int position = savedInstanceState.getInt(STATE_SELECTED_ACCOUNT);
- if (position != ListView.INVALID_POSITION) {
- mSelectAccount.setItemChecked(position, true);
- }
- }
- mSelectAccount.setOnItemClickListener(this);
- }
-
- void setupPage3(Bundle savedInstanceState) {
- mConfirmation = (TextView) mPages.findViewById(R.id.confirm);
- }
-
- void preparePage() {
- switch (mCurrentPage) {
- case PAGE_SELECT_ACCOUNT:
- if (shouldDeleteBookmarks()) {
- mSelectAccountDescription.setText(
- R.string.import_bookmarks_dialog_delete_select_account);
- } else {
- mSelectAccountDescription.setText(
- R.string.import_bookmarks_dialog_select_add_account);
- }
- break;
- case PAGE_CONFIRMATION:
- String account = getSelectedAccount().name;
- String confirmationMessage;
- if (shouldDeleteBookmarks()) {
- confirmationMessage = getActivity().getString(
- R.string.import_bookmarks_dialog_confirm_delete, account);
- } else {
- confirmationMessage = getActivity().getString(
- R.string.import_bookmarks_dialog_confirm_add, account);
- }
- mConfirmation.setText(confirmationMessage);
- break;
- }
- }
-
- int getAdjustedCheckedItemPosition(ListView list) {
- int position = list.getCheckedItemPosition();
- if (position != ListView.INVALID_POSITION) {
- position -= list.getHeaderViewsCount();
- }
- return position;
- }
-
- Account getSelectedAccount() {
- return mAccounts[getAdjustedCheckedItemPosition(mSelectAccount)];
- }
-
- boolean shouldDeleteBookmarks() {
- return getAdjustedCheckedItemPosition(mImportOrDelete) == 1;
- }
-
- @Override
- public void onItemClick(
- AdapterView<?> parent, View view, int position, long id) {
- validate();
- }
-
- void updateNavigation() {
- if (mCurrentPage == 0) {
- mNegativeButton.setText(R.string.import_bookmarks_wizard_cancel);
- } else {
- mNegativeButton.setText(R.string.import_bookmarks_wizard_previous);
- }
- if ((mCurrentPage + 1) == mPages.getChildCount()) {
- mPositiveButton.setText(R.string.import_bookmarks_wizard_done);
- } else {
- mPositiveButton.setText(R.string.import_bookmarks_wizard_next);
- }
- validate();
- }
-
- void validate() {
- switch (mCurrentPage) {
- case PAGE_IMPORT_OR_DELETE:
- mPositiveButton.setEnabled(
- mImportOrDelete.getCheckedItemPosition() != ListView.INVALID_POSITION);
- break;
- case PAGE_SELECT_ACCOUNT:
- mPositiveButton.setEnabled(
- mSelectAccount.getCheckedItemPosition() != ListView.INVALID_POSITION);
- break;
- }
- }
-
- void setupAnimations() {
- float animX = mPages.getMeasuredWidth();
- final LayoutTransition transitioner = new LayoutTransition();
- ObjectAnimator appearing = ObjectAnimator.ofFloat(this, "translationX",
- animX, 0);
- ObjectAnimator disappearing = ObjectAnimator.ofFloat(this, "translationX",
- 0, animX);
- transitioner.setAnimator(LayoutTransition.APPEARING, appearing);
- transitioner.setAnimator(LayoutTransition.DISAPPEARING, disappearing);
- mPages.setLayoutTransition(transitioner);
- }
-
- boolean next() {
- if (mCurrentPage + 1 < mPages.getChildCount()) {
- mCurrentPage++;
- preparePage();
- mPages.getChildAt(mCurrentPage).setVisibility(View.VISIBLE);
- mPages.setTargetChild(mCurrentPage);
- return true;
- }
- return false;
- }
-
- boolean prev() {
- if (mCurrentPage > 0) {
- mPages.getChildAt(mCurrentPage).setVisibility(View.GONE);
- mCurrentPage--;
- mPages.setTargetChild(mCurrentPage);
- return true;
- }
- return false;
- }
-
- void done() {
- ContentResolver resolver = getActivity().getContentResolver();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
- String accountName = getSelectedAccount().name;
- if (shouldDeleteBookmarks()) {
- // The user chose to remove their old bookmarks, delete them now
- resolver.delete(Bookmarks.CONTENT_URI,
- Bookmarks.PARENT + "=1 AND " + Bookmarks.ACCOUNT_NAME + " IS NULL", null);
- } else {
- // The user chose to migrate their old bookmarks to the account they're syncing
- migrateBookmarks(resolver, accountName);
- }
-
- // Record the fact that we turned on sync
- BrowserContract.Settings.setSyncEnabled(getActivity(), true);
- prefs.edit()
- .putString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, "com.google")
- .putString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, accountName)
- .apply();
-
- // Enable bookmark sync on all accounts
- Account[] accounts = (Account[]) getArguments().getParcelableArray("accounts");
- for (Account account : accounts) {
- if (ContentResolver.getIsSyncable(account, BrowserContract.AUTHORITY) == 0) {
- // Account wasn't syncable, enable it
- ContentResolver.setIsSyncable(account, BrowserContract.AUTHORITY, 1);
- ContentResolver.setSyncAutomatically(account, BrowserContract.AUTHORITY, true);
- }
- }
-
- dismiss();
- }
-
- @Override
- public void onClick(View v) {
- if (v == mNegativeButton) {
- if (prev()) {
- updateNavigation();
- } else {
- dismiss();
- }
- } else if (v == mPositiveButton) {
- if (next()) {
- updateNavigation();
- } else {
- done();
- }
- }
- }
-
- /**
- * Migrates bookmarks to the given account
- */
- void migrateBookmarks(ContentResolver resolver, String accountName) {
- Cursor cursor = null;
- try {
- // Re-parent the bookmarks in the default root folder
- cursor = resolver.query(Bookmarks.CONTENT_URI, new String[] { Bookmarks._ID },
- Bookmarks.ACCOUNT_NAME + " =? AND " +
- ChromeSyncColumns.SERVER_UNIQUE + " =?",
- new String[] { accountName,
- ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR },
- null);
- ContentValues values = new ContentValues();
- if (cursor == null || !cursor.moveToFirst()) {
- // The root folders don't exist for the account, create them now
- ArrayList<ContentProviderOperation> ops =
- new ArrayList<ContentProviderOperation>();
-
- // Chrome sync root folder
- values.clear();
- values.put(ChromeSyncColumns.SERVER_UNIQUE, ChromeSyncColumns.FOLDER_NAME_ROOT);
- values.put(Bookmarks.TITLE, "Google Chrome");
- values.put(Bookmarks.POSITION, 0);
- values.put(Bookmarks.IS_FOLDER, true);
- values.put(Bookmarks.DIRTY, true);
- ops.add(ContentProviderOperation.newInsert(
- Bookmarks.CONTENT_URI.buildUpon().appendQueryParameter(
- BrowserContract.CALLER_IS_SYNCADAPTER, "true").build())
- .withValues(values)
- .build());
-
- // Bookmarks folder
- values.clear();
- values.put(ChromeSyncColumns.SERVER_UNIQUE,
- ChromeSyncColumns.FOLDER_NAME_BOOKMARKS);
- values.put(Bookmarks.TITLE, "Bookmarks");
- values.put(Bookmarks.POSITION, 0);
- values.put(Bookmarks.IS_FOLDER, true);
- values.put(Bookmarks.DIRTY, true);
- ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
- .withValues(values)
- .withValueBackReference(Bookmarks.PARENT, 0)
- .build());
-
- // Bookmarks Bar folder
- values.clear();
- values.put(ChromeSyncColumns.SERVER_UNIQUE,
- ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR);
- values.put(Bookmarks.TITLE, "Bookmarks Bar");
- values.put(Bookmarks.POSITION, 0);
- values.put(Bookmarks.IS_FOLDER, true);
- values.put(Bookmarks.DIRTY, true);
- ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
- .withValues(values)
- .withValueBackReference(Bookmarks.PARENT, 1)
- .build());
-
- // Other Bookmarks folder
- values.clear();
- values.put(ChromeSyncColumns.SERVER_UNIQUE,
- ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS);
- values.put(Bookmarks.TITLE, "Other Bookmarks");
- values.put(Bookmarks.POSITION, 1000);
- values.put(Bookmarks.IS_FOLDER, true);
- values.put(Bookmarks.DIRTY, true);
- ops.add(ContentProviderOperation.newInsert(Bookmarks.CONTENT_URI)
- .withValues(values)
- .withValueBackReference(Bookmarks.PARENT, 1)
- .build());
-
- // Re-parent the existing bookmarks to the newly create bookmarks bar folder
- ops.add(ContentProviderOperation.newUpdate(Bookmarks.CONTENT_URI)
- .withValueBackReference(Bookmarks.PARENT, 2)
- .withSelection(Bookmarks.ACCOUNT_NAME + " IS NULL AND " +
- Bookmarks.PARENT + "=?",
- new String[] { Integer.toString(1) })
- .build());
-
- // Mark all non-root folder items as belonging to the new account
- values.clear();
- values.put(Bookmarks.ACCOUNT_TYPE, "com.google");
- values.put(Bookmarks.ACCOUNT_NAME, accountName);
- ops.add(ContentProviderOperation.newUpdate(Bookmarks.CONTENT_URI)
- .withValues(values)
- .withSelection(Bookmarks.ACCOUNT_NAME + " IS NULL AND " +
- Bookmarks._ID + "<>1", null)
- .build());
-
- try {
- resolver.applyBatch(BrowserContract.AUTHORITY, ops);
- } catch (RemoteException e) {
- Log.e(TAG, "failed to create root folder for account " + accountName, e);
- return;
- } catch (OperationApplicationException e) {
- Log.e(TAG, "failed to create root folder for account " + accountName, e);
- return;
- }
- } else {
- values.put(Bookmarks.PARENT, cursor.getLong(0));
- resolver.update(Bookmarks.CONTENT_URI, values, Bookmarks.PARENT + "=?",
- new String[] { Integer.toString(1) });
-
- // Mark all bookmarks at all levels as part of the new account
- values.clear();
- values.put(Bookmarks.ACCOUNT_TYPE, "com.google");
- values.put(Bookmarks.ACCOUNT_NAME, accountName);
- resolver.update(Bookmarks.CONTENT_URI, values,
- Bookmarks.ACCOUNT_NAME + " IS NULL AND " + Bookmarks._ID + "<>1",
- null);
- }
- } finally {
- if (cursor != null) cursor.close();
- }
- }
-}
diff --git a/src/com/android/browser/preferences/LabPreferencesFragment.java b/src/com/android/browser/preferences/LabPreferencesFragment.java
index a06dc3e..d9ef3df 100644
--- a/src/com/android/browser/preferences/LabPreferencesFragment.java
+++ b/src/com/android/browser/preferences/LabPreferencesFragment.java
@@ -18,14 +18,18 @@
import com.android.browser.BrowserActivity;
import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
import com.android.browser.R;
import com.android.browser.search.SearchEngine;
+import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
+import android.view.LayoutInflater;
+import android.view.View;
public class LabPreferencesFragment extends PreferenceFragment
implements OnPreferenceChangeListener {
@@ -40,32 +44,54 @@
// Load the XML preferences file
addPreferencesFromResource(R.xml.lab_preferences);
+ registerChangeListener(PreferenceKeys.PREF_ENABLE_QUICK_CONTROLS);
+ registerChangeListener(PreferenceKeys.PREF_ENABLE_USERAGENT_SWITCHER);
+ useInstantPref = findPreference(PreferenceKeys.PREF_USE_INSTANT_SEARCH);
+ }
- Preference e = findPreference(BrowserSettings.PREF_QUICK_CONTROLS);
- e.setOnPreferenceChangeListener(this);
- useInstantPref = findPreference(BrowserSettings.PREF_USE_INSTANT);
+ private void registerChangeListener(String key) {
+ Preference e = findPreference(key);
+ if (e != null) {
+ e.setOnPreferenceChangeListener(this);
+ }
}
@Override
public void onResume() {
super.onResume();
- useInstantPref.setEnabled(false);
+ if (useInstantPref != null) {
+ useInstantPref.setEnabled(false);
- // Enable the "use instant" preference only if the selected
- // search engine is google.
- if (mBrowserSettings.getSearchEngine() != null) {
- final String currentName = mBrowserSettings.getSearchEngine().getName();
- if (SearchEngine.GOOGLE.equals(currentName)) {
- useInstantPref.setEnabled(true);
+ // Enable the "use instant" preference only if the selected
+ // search engine is google.
+ if (mBrowserSettings.getSearchEngine() != null) {
+ final String currentName = mBrowserSettings.getSearchEngine().getName();
+ if (SearchEngine.GOOGLE.equals(currentName)) {
+ useInstantPref.setEnabled(true);
+ }
}
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- // Attempt to restart
- startActivity(new Intent(BrowserActivity.ACTION_RESTART, null,
- getActivity(), BrowserActivity.class));
+ String key = preference.getKey();
+ if (PreferenceKeys.PREF_ENABLE_QUICK_CONTROLS.equals(key)) {
+ // Attempt to restart
+ startActivity(new Intent(BrowserActivity.ACTION_RESTART, null,
+ getActivity(), BrowserActivity.class));
+ }
+ if (PreferenceKeys.PREF_ENABLE_USERAGENT_SWITCHER.equals(key)) {
+ if ((Boolean)newValue) {
+ // Show the help
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ View content = inflater.inflate(R.layout.help_dialog_useragent_switcher, null);
+ new AlertDialog.Builder(getActivity())
+ .setView(content)
+ .setNeutralButton(android.R.string.ok, null)
+ .show();
+ }
+ }
return true;
}
}
diff --git a/src/com/android/browser/preferences/MinFontSizePreference.java b/src/com/android/browser/preferences/MinFontSizePreference.java
new file mode 100644
index 0000000..22092b0
--- /dev/null
+++ b/src/com/android/browser/preferences/MinFontSizePreference.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 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.preferences;
+
+import com.android.browser.R;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+public class MinFontSizePreference extends Preference implements OnSeekBarChangeListener {
+
+ // range from 1:6..24
+ static final int MIN = 5;
+ static final int MAX = 23;
+ private int mProgress;
+ View mRoot;
+
+ public MinFontSizePreference(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public MinFontSizePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public MinFontSizePreference(Context context) {
+ super(context);
+ }
+
+ @Override
+ public View getView(View convertView, ViewGroup parent) {
+ if (mRoot == null) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ mRoot = inflater.inflate(R.layout.min_font_size, parent, false);
+ SeekBar seek = (SeekBar) mRoot.findViewById(R.id.seekbar);
+ seek.setMax((MAX - MIN));
+ seek.setProgress(mProgress);
+ seek.setOnSeekBarChangeListener(this);
+ }
+ return mRoot;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ mProgress = restoreValue ? getPersistedInt(mProgress)
+ : (Integer) defaultValue;
+ mProgress -= 1;
+ }
+
+ @Override
+ public void onProgressChanged(
+ SeekBar seekBar, int progress, boolean fromUser) {
+ if (fromUser) {
+ if (progress == 0) {
+ persistInt(1);
+ } else {
+ persistInt(progress + MIN + 1);
+ }
+ }
+ mRoot.invalidate();
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ /*
+ * Suppose a client uses this preference type without persisting. We
+ * must save the instance state so it is able to, for example, survive
+ * orientation changes.
+ */
+
+ final Parcelable superState = super.onSaveInstanceState();
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent
+ return superState;
+ }
+
+ // Save the instance state
+ final SavedState myState = new SavedState(superState);
+ myState.progress = mProgress;
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (!state.getClass().equals(SavedState.class)) {
+ // Didn't save state for us in onSaveInstanceState
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ // Restore the instance state
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ mProgress = myState.progress;
+ notifyChanged();
+ }
+
+ /**
+ * SavedState, a subclass of {@link BaseSavedState}, will store the state
+ * of MyPreference, a subclass of Preference.
+ * <p>
+ * It is important to always call through to super methods.
+ */
+ private static class SavedState extends BaseSavedState {
+ int progress;
+
+ public SavedState(Parcel source) {
+ super(source);
+
+ // Restore the click counter
+ progress = source.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+
+ // Save the click counter
+ dest.writeInt(progress);
+ }
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+}
diff --git a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
index 2266608..35e6e43 100644
--- a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
@@ -16,7 +16,7 @@
package com.android.browser.preferences;
-import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
import com.android.browser.R;
import android.app.Activity;
@@ -28,18 +28,14 @@
public class PrivacySecurityPreferencesFragment extends PreferenceFragment
implements Preference.OnPreferenceChangeListener {
- private BrowserSettings mSettings;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mSettings = BrowserSettings.getInstance();
-
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.privacy_security_preferences);
- Preference e = findPreference(BrowserSettings.PREF_CLEAR_HISTORY);
+ Preference e = findPreference(PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY);
e.setOnPreferenceChangeListener(this);
}
@@ -50,7 +46,7 @@
@Override
public boolean onPreferenceChange(Preference pref, Object objValue) {
- if (pref.getKey().equals(BrowserSettings.PREF_CLEAR_HISTORY)
+ if (pref.getKey().equals(PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY)
&& ((Boolean) objValue).booleanValue() == true) {
// Need to tell the browser to remove the parent/child relationship
// between tabs
diff --git a/src/com/android/browser/preferences/WebViewPreview.java b/src/com/android/browser/preferences/WebViewPreview.java
new file mode 100644
index 0000000..a269dbd
--- /dev/null
+++ b/src/com/android/browser/preferences/WebViewPreview.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 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.preferences;
+
+import com.android.browser.BrowserSettings;
+import com.android.browser.R;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+
+public class WebViewPreview extends Preference implements OnSharedPreferenceChangeListener {
+
+ // 80 char line width limit? Rules are made to be broken.
+ static final String HTML_FORMAT = "<html><head><style type=\"text/css\">p { margin: 2px auto;}</style><body><p style=\"font-size: .4em\">%s</p><p style=\"font-size: .7em\">%s</p><p style=\"font-size: 1em\">%s</p><p style=\"font-size: 1.3em\">%s</p><p style=\"font-size: 1.6em\">%s</p></body></html>";
+
+ String HTML;
+ private View mRoot;
+ private WebView mWebView;
+
+ public WebViewPreview(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public WebViewPreview(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public WebViewPreview(Context context) {
+ super(context);
+ init(context);
+ }
+
+ void init(Context context) {
+ Resources res = context.getResources();
+ Object[] visualNames = res.getStringArray(R.array.pref_text_size_choices);
+ HTML = String.format(HTML_FORMAT, visualNames);
+ }
+
+ void updatePreview() {
+ if (mWebView == null) return;
+
+ WebSettings ws = mWebView.getSettings();
+ BrowserSettings bs = BrowserSettings.getInstance();
+ ws.setMinimumFontSize(bs.getMinimumFontSize());
+ ws.setTextSize(bs.getTextSize());
+ mWebView.loadData(HTML, "text/html", "utf-8");
+ }
+
+ @Override
+ public View getView(View convertView, ViewGroup parent) {
+ if (mWebView == null) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ mRoot = inflater.inflate(R.layout.webview_preview, parent, false);
+ mWebView = (WebView) mRoot.findViewById(R.id.webview);
+ mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ }
+ updatePreview();
+ return mRoot;
+ }
+
+ @Override
+ protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
+ super.onAttachedToHierarchy(preferenceManager);
+ getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ protected void onPrepareForRemoval() {
+ getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ super.onPrepareForRemoval();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ updatePreview();
+ }
+
+}
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/provider/BrowserProvider.java
similarity index 98%
rename from src/com/android/browser/BrowserProvider.java
rename to src/com/android/browser/provider/BrowserProvider.java
index f69665c..b55b84a 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/provider/BrowserProvider.java
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-package com.android.browser;
+package com.android.browser.provider;
+import com.android.browser.BrowserSettings;
+import com.android.browser.R;
import com.android.browser.search.SearchEngine;
import android.app.SearchManager;
@@ -40,7 +42,6 @@
import android.preference.PreferenceManager;
import android.provider.Browser;
import android.provider.Browser.BookmarkColumns;
-import android.provider.Settings;
import android.speech.RecognizerResultsIntent;
import android.text.TextUtils;
import android.util.Log;
@@ -58,14 +59,14 @@
private SQLiteOpenHelper mOpenHelper;
private BackupManager mBackupManager;
- private static final String sDatabaseName = "browser.db";
+ static final String sDatabaseName = "browser.db";
private static final String TAG = "BrowserProvider";
private static final String ORDER_BY = "visits DESC, date DESC";
private static final String PICASA_URL = "http://picasaweb.google.com/m/" +
"viewer?source=androidclient";
- private static final String[] TABLE_NAMES = new String[] {
+ static final String[] TABLE_NAMES = new String[] {
"bookmarks", "searches"
};
private static final String[] SUGGEST_PROJECTION = new String[] {
@@ -113,7 +114,7 @@
// make sure that these match the index of TABLE_NAMES
- private static final int URI_MATCH_BOOKMARKS = 0;
+ static final int URI_MATCH_BOOKMARKS = 0;
private static final int URI_MATCH_SEARCHES = 1;
// (id % 10) should match the table name index
private static final int URI_MATCH_BOOKMARKS_ID = 10;
@@ -179,7 +180,7 @@
// XXX: This is a major hack to remove our dependency on gsf constants and
// its content provider. http://b/issue?id=2425179
- static String getClientId(ContentResolver cr) {
+ public static String getClientId(ContentResolver cr) {
String ret = "android-google";
Cursor legacyClientIdCursor = null;
Cursor searchClientIdCursor = null;
@@ -245,7 +246,7 @@
return sb;
}
- private static class DatabaseHelper extends SQLiteOpenHelper {
+ static class DatabaseHelper extends SQLiteOpenHelper {
private Context mContext;
public DatabaseHelper(Context context) {
@@ -839,7 +840,7 @@
* by the SearchDialog when the BrowserActivity is in voice search mode.
* @param results Strings to display in the dropdown from the SearchDialog
*/
- /* package */ void setQueryResults(ArrayList<String> results) {
+ public /* package */ void setQueryResults(ArrayList<String> results) {
synchronized (mResultsCursorLock) {
if (results == null) {
mResultsCursor = null;
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index d154f20..d9760e5 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -21,6 +21,7 @@
import com.android.browser.BookmarkUtils;
import com.android.browser.BrowserBookmarksPage;
import com.android.browser.R;
+import com.android.browser.UrlUtils;
import com.android.browser.widget.BookmarkThumbnailWidgetProvider;
import com.android.common.content.SyncStateContentProviderHelper;
@@ -63,6 +64,7 @@
import android.text.TextUtils;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
@@ -86,6 +88,8 @@
static final String TABLE_HISTORY_JOIN_IMAGES = "history LEFT OUTER JOIN images " +
"ON history.url = images." + Images.URL;
+ static final String VIEW_ACCOUNTS = "v_accounts";
+
static final String FORMAT_COMBINED_JOIN_SUBQUERY_JOIN_IMAGES =
"history LEFT OUTER JOIN (%s) bookmarks " +
"ON history.url = bookmarks.url LEFT OUTER JOIN images " +
@@ -203,6 +207,7 @@
map = ACCOUNTS_PROJECTION_MAP;
map.put(Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_TYPE);
map.put(Accounts.ACCOUNT_NAME, Accounts.ACCOUNT_NAME);
+ map.put(Accounts.ROOT_ID, Accounts.ROOT_ID);
// Bookmarks
map = BOOKMARKS_PROJECTION_MAP;
@@ -328,7 +333,7 @@
final class DatabaseHelper extends SQLiteOpenHelper {
static final String DATABASE_NAME = "browser2.db";
- static final int DATABASE_VERSION = 26;
+ static final int DATABASE_VERSION = 28;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@@ -390,15 +395,120 @@
Settings.VALUE + " TEXT NOT NULL" +
");");
+ createAccountsView(db);
+
mSyncHelper.createDatabase(db);
- createDefaultBookmarks(db);
+ if (!importFromBrowserProvider(db)) {
+ createDefaultBookmarks(db);
+ }
+
+ enableSync(db);
+ }
+
+ void enableSync(SQLiteDatabase db) {
+ ContentValues values = new ContentValues();
+ values.put(Settings.KEY, Settings.KEY_SYNC_ENABLED);
+ values.put(Settings.VALUE, 1);
+ insertSettingsInTransaction(db, values);
+ }
+
+ boolean importFromBrowserProvider(SQLiteDatabase db) {
+ Context context = getContext();
+ File oldDbFile = context.getDatabasePath(BrowserProvider.sDatabaseName);
+ if (oldDbFile.exists()) {
+ BrowserProvider.DatabaseHelper helper =
+ new BrowserProvider.DatabaseHelper(context);
+ SQLiteDatabase oldDb = helper.getWritableDatabase();
+ Cursor c = null;
+ try {
+ String table = BrowserProvider.TABLE_NAMES[BrowserProvider.URI_MATCH_BOOKMARKS];
+ // Import bookmarks
+ c = oldDb.query(table,
+ new String[] {
+ BookmarkColumns.URL, // 0
+ BookmarkColumns.TITLE, // 1
+ BookmarkColumns.FAVICON, // 2
+ BookmarkColumns.TOUCH_ICON, // 3
+ }, BookmarkColumns.BOOKMARK + "!=0", null,
+ null, null, null);
+ if (c != null) {
+ while (c.moveToNext()) {
+ ContentValues values = new ContentValues();
+ values.put(Bookmarks.URL, c.getString(0));
+ values.put(Bookmarks.TITLE, c.getString(1));
+ values.put(Bookmarks.POSITION, 0);
+ values.put(Bookmarks.PARENT, FIXED_ID_ROOT);
+ ContentValues imageValues = new ContentValues();
+ imageValues.put(Images.URL, c.getString(0));
+ imageValues.put(Images.FAVICON, c.getBlob(2));
+ imageValues.put(Images.TOUCH_ICON, c.getBlob(3));
+ db.insertOrThrow(TABLE_IMAGES, Images.THUMBNAIL, imageValues);
+ db.insertOrThrow(TABLE_BOOKMARKS, Bookmarks.DIRTY, values);
+ }
+ c.close();
+ }
+ // Import history
+ c = oldDb.query(table,
+ new String[] {
+ BookmarkColumns.URL, // 0
+ BookmarkColumns.TITLE, // 1
+ BookmarkColumns.VISITS, // 2
+ BookmarkColumns.DATE, // 3
+ BookmarkColumns.CREATED, // 4
+ }, null, null, null, null, null);
+ if (c != null) {
+ while (c.moveToNext()) {
+ ContentValues values = new ContentValues();
+ values.put(History.URL, c.getString(0));
+ values.put(History.TITLE, c.getString(1));
+ values.put(History.VISITS, c.getInt(2));
+ values.put(History.DATE_LAST_VISITED, c.getLong(3));
+ values.put(History.DATE_CREATED, c.getLong(4));
+ db.insertOrThrow(TABLE_HISTORY, History.FAVICON, values);
+ }
+ c.close();
+ }
+ // Wipe the old DB, in case the delete fails.
+ oldDb.delete(table, null, null);
+ } finally {
+ if (c != null) c.close();
+ oldDb.close();
+ helper.close();
+ }
+ if (!oldDbFile.delete()) {
+ oldDbFile.deleteOnExit();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ void createAccountsView(SQLiteDatabase db) {
+ db.execSQL("CREATE VIEW IF NOT EXISTS v_accounts AS "
+ + "SELECT NULL AS " + Accounts.ACCOUNT_NAME
+ + ", NULL AS " + Accounts.ACCOUNT_TYPE
+ + ", " + FIXED_ID_ROOT + " AS " + Accounts.ROOT_ID
+ + " UNION ALL SELECT " + Accounts.ACCOUNT_NAME
+ + ", " + Accounts.ACCOUNT_TYPE + ", "
+ + Bookmarks._ID + " AS " + Accounts.ROOT_ID
+ + " FROM " + TABLE_BOOKMARKS + " WHERE "
+ + ChromeSyncColumns.SERVER_UNIQUE + " = \""
+ + ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR + "\" AND "
+ + Bookmarks.IS_DELETED + " = 0");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // TODO write upgrade logic
- db.execSQL("DROP VIEW IF EXISTS combined");
+ if (oldVersion < 28) {
+ enableSync(db);
+ }
+ if (oldVersion < 27) {
+ createAccountsView(db);
+ }
+ if (oldVersion < 26) {
+ db.execSQL("DROP VIEW IF EXISTS combined");
+ }
if (oldVersion < 25) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY);
@@ -650,10 +760,8 @@
String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
switch (match) {
case ACCOUNTS: {
- qb.setTables(TABLE_BOOKMARKS);
+ qb.setTables(VIEW_ACCOUNTS);
qb.setProjectionMap(ACCOUNTS_PROJECTION_MAP);
- qb.setDistinct(true);
- qb.appendWhere(Bookmarks.ACCOUNT_NAME + " IS NOT NULL");
break;
}
@@ -847,10 +955,6 @@
&& projection == null) {
projection = Browser.HISTORY_PROJECTION;
}
- if (match == LEGACY) {
- uri = BookmarkUtils.addAccountInfo(getContext(),
- uri.buildUpon()).build();
- }
String[] args = createCombinedQuery(uri, projection, qb);
if (selectionArgs == null) {
selectionArgs = args;
@@ -899,19 +1003,6 @@
selection = DatabaseUtils.concatenateWhere(selection,
Bookmarks.IS_DELETED + "=0 AND " + Bookmarks.IS_FOLDER + "=0");
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
- String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
- selection = DatabaseUtils.concatenateWhere(selection,
- Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=? ");
- selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
- new String[] { accountType, accountName });
- } else {
- selection = DatabaseUtils.concatenateWhere(selection,
- Bookmarks.ACCOUNT_TYPE + " IS NULL AND " +
- Bookmarks.ACCOUNT_NAME + " IS NULL ");
- }
Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_BOOKMARKS,
SUGGEST_PROJECTION, selection, selectionArgs, null, null,
DEFAULT_BOOKMARKS_SORT_ORDER, null);
@@ -1051,8 +1142,6 @@
String[] projection = new String[] { Combined._ID,
Combined.IS_BOOKMARK, Combined.URL };
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
- uri = BookmarkUtils.addAccountInfo(getContext(), uri.buildUpon())
- .build();
String[] args = createCombinedQuery(uri, projection, qb);
if (selectionArgs == null) {
selectionArgs = args;
@@ -1122,14 +1211,6 @@
values.remove(BookmarkColumns.DATE);
values.remove(BookmarkColumns.VISITS);
values.remove(BookmarkColumns.USER_ENTERED);
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(getContext());
- String accountType = prefs.getString(
- BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
- String accountName = prefs.getString(
- BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- values.put(Bookmarks.ACCOUNT_TYPE, accountType);
- values.put(Bookmarks.ACCOUNT_NAME, accountName);
values.put(Bookmarks.IS_FOLDER, 0);
}
}
@@ -1523,9 +1604,35 @@
String[] selectionArgs, boolean callerIsSyncAdapter) {
int count = 0;
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Cursor cursor = db.query(TABLE_BOOKMARKS,
- new String[] { Bookmarks._ID, Bookmarks.VERSION, Bookmarks.URL },
+ final String[] bookmarksProjection = new String[] {
+ Bookmarks._ID, // 0
+ Bookmarks.VERSION, // 1
+ Bookmarks.URL, // 2
+ Bookmarks.TITLE, // 3
+ Bookmarks.IS_FOLDER, // 4
+ Bookmarks.ACCOUNT_NAME, // 5
+ Bookmarks.ACCOUNT_TYPE, // 6
+ };
+ Cursor cursor = db.query(TABLE_BOOKMARKS, bookmarksProjection,
selection, selectionArgs, null, null, null);
+ boolean updatingParent = values.containsKey(Bookmarks.PARENT);
+ String parentAccountName = null;
+ String parentAccountType = null;
+ if (updatingParent) {
+ long parent = values.getAsLong(Bookmarks.PARENT);
+ Cursor c = db.query(TABLE_BOOKMARKS, new String[] {
+ Bookmarks.ACCOUNT_NAME, Bookmarks.ACCOUNT_TYPE},
+ "_id = ?", new String[] { Long.toString(parent) },
+ null, null, null);
+ if (c.moveToFirst()) {
+ parentAccountName = c.getString(0);
+ parentAccountType = c.getString(1);
+ c.close();
+ }
+ } else if (values.containsKey(Bookmarks.ACCOUNT_NAME)
+ || values.containsKey(Bookmarks.ACCOUNT_TYPE)) {
+ // TODO: Implement if needed (no one needs this yet)
+ }
try {
String[] args = new String[1];
// Mark the bookmark dirty if the caller isn't a sync adapter
@@ -1542,12 +1649,47 @@
ContentValues imageValues = extractImageValues(values, url);
while (cursor.moveToNext()) {
- args[0] = cursor.getString(0);
- if (!callerIsSyncAdapter) {
- // increase the local version for non-sync changes
- values.put(Bookmarks.VERSION, cursor.getLong(1) + 1);
+ long id = cursor.getLong(0);
+ args[0] = Long.toString(id);
+ String accountName = cursor.getString(5);
+ String accountType = cursor.getString(6);
+ // If we are updating the parent and either the account name or
+ // type do not match that of the new parent
+ if (updatingParent
+ && (!TextUtils.equals(accountName, parentAccountName)
+ || !TextUtils.equals(accountType, parentAccountType))) {
+ // Parent is a different account
+ // First, insert a new bookmark/folder with the new account
+ // Then, if this is a folder, reparent all it's children
+ // Finally, delete the old bookmark/folder
+ ContentValues newValues = valuesFromCursor(cursor);
+ newValues.putAll(values);
+ newValues.remove(Bookmarks._ID);
+ newValues.remove(Bookmarks.VERSION);
+ newValues.put(Bookmarks.ACCOUNT_NAME, parentAccountName);
+ newValues.put(Bookmarks.ACCOUNT_TYPE, parentAccountType);
+ Uri insertUri = insertInTransaction(Bookmarks.CONTENT_URI,
+ newValues, callerIsSyncAdapter);
+ long newId = ContentUris.parseId(insertUri);
+ if (cursor.getInt(4) != 0) {
+ // This is a folder, reparent
+ ContentValues updateChildren = new ContentValues(1);
+ updateChildren.put(Bookmarks.PARENT, newId);
+ count += updateBookmarksInTransaction(updateChildren,
+ Bookmarks.PARENT + "=?", new String[] {
+ Long.toString(id)}, callerIsSyncAdapter);
+ }
+ // Now, delete the old one
+ Uri uri = ContentUris.withAppendedId(Bookmarks.CONTENT_URI, id);
+ deleteInTransaction(uri, null, null, callerIsSyncAdapter);
+ count += 1;
+ } else {
+ if (!callerIsSyncAdapter) {
+ // increase the local version for non-sync changes
+ values.put(Bookmarks.VERSION, cursor.getLong(1) + 1);
+ }
+ count += db.update(TABLE_BOOKMARKS, values, "_id=?", args);
}
- count += db.update(TABLE_BOOKMARKS, values, "_id=?", args);
// Update the images over in their table
if (imageValues != null) {
@@ -1570,6 +1712,29 @@
return count;
}
+ ContentValues valuesFromCursor(Cursor c) {
+ int count = c.getColumnCount();
+ ContentValues values = new ContentValues(count);
+ String[] colNames = c.getColumnNames();
+ for (int i = 0; i < count; i++) {
+ switch (c.getType(i)) {
+ case Cursor.FIELD_TYPE_BLOB:
+ values.put(colNames[i], c.getBlob(i));
+ break;
+ case Cursor.FIELD_TYPE_FLOAT:
+ values.put(colNames[i], c.getFloat(i));
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ values.put(colNames[i], c.getLong(i));
+ break;
+ case Cursor.FIELD_TYPE_STRING:
+ values.put(colNames[i], c.getString(i));
+ break;
+ }
+ }
+ return values;
+ }
+
/**
* Does a query to find the matching bookmarks and updates each one with the provided values.
*/
@@ -1724,7 +1889,7 @@
case SUGGEST_COLUMN_INTENT_DATA_ID:
case SUGGEST_COLUMN_TEXT_2_TEXT_ID:
case SUGGEST_COLUMN_TEXT_2_URL_ID:
- return mSource.getString(URL_INDEX);
+ return UrlUtils.stripUrl(mSource.getString(URL_INDEX));
case SUGGEST_COLUMN_TEXT_1_ID:
return mSource.getString(TITLE_INDEX);
case SUGGEST_COLUMN_ICON_1_ID:
diff --git a/src/com/android/browser/search/SearchEngines.java b/src/com/android/browser/search/SearchEngines.java
index a159f17..fd967f9 100644
--- a/src/com/android/browser/search/SearchEngines.java
+++ b/src/com/android/browser/search/SearchEngines.java
@@ -32,7 +32,7 @@
private static final String TAG = "SearchEngines";
public static SearchEngine getDefaultSearchEngine(Context context) {
- if (BrowserSettings.getInstance().useInstant()) {
+ if (BrowserSettings.getInstance().useInstantSearch()) {
return new InstantSearchEngine(context, DefaultSearchEngine.create(context));
}
diff --git a/src/com/android/browser/view/BookmarkContainer.java b/src/com/android/browser/view/BookmarkContainer.java
new file mode 100644
index 0000000..260b05e
--- /dev/null
+++ b/src/com/android/browser/view/BookmarkContainer.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 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.view;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewConfiguration;
+import android.widget.RelativeLayout;
+
+public class BookmarkContainer extends RelativeLayout implements OnClickListener {
+
+ private OnClickListener mClickListener;
+
+ public BookmarkContainer(Context context) {
+ super(context);
+ init();
+ }
+
+ public BookmarkContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public BookmarkContainer(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ void init() {
+ setFocusable(true);
+ super.setOnClickListener(this);
+ }
+
+ @Override
+ public void setBackgroundDrawable(Drawable d) {
+ super.setBackgroundDrawable(d);
+ }
+
+ @Override
+ public void setOnClickListener(OnClickListener l) {
+ mClickListener = l;
+ }
+
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+ updateTransitionDrawable(isPressed());
+ }
+
+ void updateTransitionDrawable(boolean pressed) {
+ final int longPressTimeout = ViewConfiguration.getLongPressTimeout();
+ Drawable selector = getBackground();
+ if (selector != null && selector instanceof StateListDrawable) {
+ Drawable d = ((StateListDrawable)selector).getCurrent();
+ if (d != null && d instanceof TransitionDrawable) {
+ if (pressed && isLongClickable()) {
+ ((TransitionDrawable) d).startTransition(longPressTimeout);
+ } else {
+ ((TransitionDrawable) d).resetTransition();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ updateTransitionDrawable(false);
+ if (mClickListener != null) {
+ mClickListener.onClick(view);
+ }
+ }
+}
diff --git a/src/com/android/browser/view/BookmarkExpandableGridView.java b/src/com/android/browser/view/BookmarkExpandableGridView.java
new file mode 100644
index 0000000..f6b9f19
--- /dev/null
+++ b/src/com/android/browser/view/BookmarkExpandableGridView.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2011 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.view;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.provider.BrowserContract;
+import android.util.AttributeSet;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.browser.BookmarkDragHandler;
+import com.android.browser.BookmarkDragHandler.BookmarkDragAdapter;
+import com.android.browser.BookmarkDragHandler.BookmarkDragState;
+import com.android.browser.BreadCrumbView;
+import com.android.browser.BrowserBookmarksAdapter;
+import com.android.browser.BrowserBookmarksPage.ExtraDragState;
+import com.android.browser.R;
+import com.android.internal.view.menu.MenuBuilder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class BookmarkExpandableGridView extends ExpandableListView
+ implements BreadCrumbView.Controller {
+
+ private BookmarkAccountAdapter mAdapter;
+ private int mColumnWidth;
+ private Context mContext;
+ private OnChildClickListener mOnChildClickListener;
+ private ContextMenuInfo mContextMenuInfo = null;
+ private OnCreateContextMenuListener mOnCreateContextMenuListener;
+ private boolean mLongClickable;
+ private BreadCrumbView.Controller mBreadcrumbController;
+ private BookmarkDragHandler mDragHandler;
+
+ public BookmarkExpandableGridView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public BookmarkExpandableGridView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public BookmarkExpandableGridView(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ void init(Context context) {
+ mContext = context;
+ setItemsCanFocus(true);
+ setLongClickable(false);
+ mAdapter = new BookmarkAccountAdapter(mContext);
+ super.setAdapter(mAdapter);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mAdapter.measureChildren();
+ }
+
+ @Override
+ public void setAdapter(ExpandableListAdapter adapter) {
+ throw new RuntimeException("Not supported");
+ }
+
+ public void setColumnWidthFromLayout(int layout) {
+ LayoutInflater infalter = LayoutInflater.from(mContext);
+ View v = infalter.inflate(layout, this, false);
+ v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ mColumnWidth = v.getMeasuredWidth();
+ }
+
+ public void setHorizontalSpacing(int horizontalSpacing) {
+ // TODO Auto-generated method stub
+ }
+
+ public void clearAccounts() {
+ mAdapter.clear();
+ }
+
+ public void addAccount(String accountName, BrowserBookmarksAdapter adapter) {
+ // First, check if it already exists
+ int indexOf = mAdapter.mGroups.indexOf(accountName);
+ if (indexOf >= 0) {
+ BrowserBookmarksAdapter existing = mAdapter.mChildren.get(indexOf);
+ if (existing != adapter) {
+ existing.unregisterDataSetObserver(mAdapter.mObserver);
+ // Replace the existing one
+ mAdapter.mChildren.remove(indexOf);
+ mAdapter.mChildren.add(indexOf, adapter);
+ adapter.registerDataSetObserver(mAdapter.mObserver);
+ }
+ } else {
+ mAdapter.mGroups.add(accountName);
+ mAdapter.mChildren.add(adapter);
+ adapter.registerDataSetObserver(mAdapter.mObserver);
+ }
+ mAdapter.notifyDataSetChanged();
+ expandGroup(mAdapter.getGroupCount() - 1);
+ }
+
+ @Override
+ public void setOnChildClickListener(OnChildClickListener onChildClickListener) {
+ mOnChildClickListener = onChildClickListener;
+ }
+
+ @Override
+ public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
+ mOnCreateContextMenuListener = l;
+ if (!mLongClickable) {
+ mLongClickable = true;
+ if (mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+
+ @Override
+ public void createContextMenu(ContextMenu menu) {
+ // The below is copied from View - we want to bypass the override
+ // in AbsListView
+
+ ContextMenuInfo menuInfo = getContextMenuInfo();
+
+ // Sets the current menu info so all items added to menu will have
+ // my extra info set.
+ ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);
+
+ onCreateContextMenu(menu);
+ if (mOnCreateContextMenuListener != null) {
+ mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
+ }
+
+ // Clear the extra information so subsequent items that aren't mine don't
+ // have my extra info.
+ ((MenuBuilder)menu).setCurrentMenuInfo(null);
+
+ if (mParent != null) {
+ mParent.createContextMenu(menu);
+ }
+ }
+
+ @Override
+ public boolean showContextMenuForChild(View originalView) {
+ int groupPosition = (Integer) originalView.getTag(R.id.group_position);
+ int childPosition = (Integer) originalView.getTag(R.id.child_position);
+
+ mContextMenuInfo = new BookmarkContextMenuInfo(childPosition,
+ groupPosition);
+ if (getParent() != null) {
+ getParent().showContextMenuForChild(this);
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onTop(BreadCrumbView view, int level, Object data) {
+ if (mBreadcrumbController != null) {
+ mBreadcrumbController.onTop(view, level, data);
+ }
+ }
+
+ public void setBreadcrumbController(BreadCrumbView.Controller controller) {
+ mBreadcrumbController = controller;
+ }
+
+ @Override
+ protected ContextMenuInfo getContextMenuInfo() {
+ return mContextMenuInfo;
+ }
+
+ public BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
+ return mAdapter.mChildren.get(groupPosition);
+ }
+
+ public BookmarkDragAdapter getDragAdapter() {
+ return mDragAdapter;
+ }
+
+ public void showContextMenuForState(BookmarkDragState state) {
+ ExtraDragState extraState = (ExtraDragState) state.extraState;
+ mContextMenuInfo = new BookmarkContextMenuInfo(
+ extraState.childPosition,
+ extraState.groupPosition);
+ if (getParent() != null) {
+ getParent().showContextMenuForChild(BookmarkExpandableGridView.this);
+ }
+ }
+
+ private BookmarkDragAdapter mDragAdapter = new BookmarkDragAdapter() {
+
+ @Override
+ public void setBookmarkDragHandler(BookmarkDragHandler handler) {
+ mDragHandler = handler;
+ }
+
+ @Override
+ public Cursor getItemForView(View v) {
+ int groupPosition = (Integer) v.getTag(R.id.group_position);
+ int childPosition = (Integer) v.getTag(R.id.child_position);
+ return getChildAdapter(groupPosition).getItem(childPosition);
+ }
+
+ };
+
+ private OnClickListener mChildClickListener = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ int groupPosition = (Integer) v.getTag(R.id.group_position);
+ int childPosition = (Integer) v.getTag(R.id.child_position);
+ long id = (Long) v.getTag(R.id.child_id);
+ if (mOnChildClickListener != null) {
+ mOnChildClickListener.onChildClick(BookmarkExpandableGridView.this,
+ v, groupPosition, childPosition, id);
+ }
+ }
+ };
+
+ private OnClickListener mGroupOnClickListener = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ int groupPosition = (Integer) v.getTag(R.id.group_position);
+ if (isGroupExpanded(groupPosition)) {
+ collapseGroup(groupPosition);
+ } else {
+ expandGroup(groupPosition, true);
+ }
+ }
+ };
+
+ private OnLongClickListener mChildOnLongClickListener = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ ExtraDragState state = new ExtraDragState();
+ state.groupPosition = (Integer) v.getTag(R.id.group_position);
+ state.childPosition = (Integer) v.getTag(R.id.child_position);
+ long id = (Long) v.getTag(R.id.child_id);
+ Cursor c = getChildAdapter(state.groupPosition)
+ .getItem(state.childPosition);
+ return mDragHandler.startDrag(v, c, id, state);
+ }
+ };
+
+ public BreadCrumbView getBreadCrumbs(int groupPosition) {
+ return mAdapter.getBreadCrumbView(groupPosition);
+ }
+
+ class BookmarkAccountAdapter extends BaseExpandableListAdapter {
+ ArrayList<BrowserBookmarksAdapter> mChildren;
+ ArrayList<String> mGroups;
+ HashMap<Integer, BreadCrumbView> mBreadcrumbs =
+ new HashMap<Integer, BreadCrumbView>();
+ LayoutInflater mInflater;
+ int mRowCount = 1; // assume at least 1 child fits in a row
+ int mLastViewWidth = -1;
+ int mRowPadding = -1;
+ DataSetObserver mObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ notifyDataSetChanged();
+ }
+ };
+
+ public BookmarkAccountAdapter(Context context) {
+ mContext = context;
+ mInflater = LayoutInflater.from(mContext);
+ mChildren = new ArrayList<BrowserBookmarksAdapter>();
+ mGroups = new ArrayList<String>();
+ }
+
+ public void clear() {
+ mGroups.clear();
+ mChildren.clear();
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public Object getChild(int groupPosition, int childPosition) {
+ return mChildren.get(groupPosition).getItem(childPosition);
+ }
+
+ @Override
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ @Override
+ public View getChildView(int groupPosition, int childPosition,
+ boolean isLastChild, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.bookmark_grid_row, parent, false);
+ }
+ LinearLayout row = (LinearLayout) convertView;
+ row.setPadding(
+ mRowPadding,
+ row.getPaddingTop(),
+ mRowPadding,
+ row.getPaddingBottom());
+ if (row.getChildCount() > mRowCount) {
+ row.removeViews(mRowCount, row.getChildCount() - mRowCount);
+ }
+ for (int i = 0; i < mRowCount; i++) {
+ View cv = null;
+ if (row.getChildCount() > i) {
+ cv = row.getChildAt(i);
+ }
+ int realChildPosition = (childPosition * mRowCount) + i;
+ BrowserBookmarksAdapter childAdapter = mChildren.get(groupPosition);
+ if (realChildPosition < childAdapter.getCount()) {
+ View v = childAdapter.getView(realChildPosition, cv, row);
+ v.setTag(R.id.group_position, groupPosition);
+ v.setTag(R.id.child_position, realChildPosition);
+ v.setTag(R.id.child_id, childAdapter.getItemId(realChildPosition));
+ v.setOnClickListener(mChildClickListener);
+ v.setLongClickable(mLongClickable);
+ if (mDragHandler != null) {
+ v.setOnLongClickListener(mChildOnLongClickListener);
+ mDragHandler.registerBookmarkDragHandler(v);
+ }
+ if (cv == null) {
+ row.addView(v);
+ } else if (cv != v) {
+ row.removeViewAt(i);
+ row.addView(v, i);
+ } else {
+ cv.setVisibility(View.VISIBLE);
+ }
+ } else if (cv != null) {
+ cv.setVisibility(View.GONE);
+ }
+ }
+ return row;
+ }
+
+ @Override
+ public int getChildrenCount(int groupPosition) {
+ return (int) Math.ceil(
+ mChildren.get(groupPosition).getCount() / (float)mRowCount);
+ }
+
+ @Override
+ public Object getGroup(int groupPosition) {
+ return mChildren.get(groupPosition);
+ }
+
+ @Override
+ public int getGroupCount() {
+ return mGroups.size();
+ }
+
+ public void measureChildren() {
+ int viewWidth = getMeasuredWidth();
+ if (mLastViewWidth == viewWidth) return;
+
+ ViewGroup parent = (ViewGroup) mInflater.inflate(R.layout.bookmark_grid_row, null);
+ viewWidth -= parent.getPaddingLeft() + parent.getPaddingRight();
+ int rowCount = viewWidth / mColumnWidth;
+ int rowPadding = (viewWidth - (rowCount * mColumnWidth)) / 2;
+ boolean notify = rowCount != mRowCount || rowPadding != mRowPadding;
+ mRowCount = rowCount;
+ mRowPadding = rowPadding;
+ mLastViewWidth = viewWidth;
+ if (notify) {
+ notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ @Override
+ public View getGroupView(int groupPosition, boolean isExpanded,
+ View view, ViewGroup parent) {
+ if (view == null) {
+ view = mInflater.inflate(R.layout.bookmark_group_view, parent, false);
+ view.setOnClickListener(mGroupOnClickListener);
+ }
+ view.setTag(R.id.group_position, groupPosition);
+ FrameLayout crumbHolder = (FrameLayout) view.findViewById(R.id.crumb_holder);
+ crumbHolder.removeAllViews();
+ BreadCrumbView crumbs = getBreadCrumbView(groupPosition);
+ if (crumbs.getParent() != null) {
+ ((ViewGroup)crumbs.getParent()).removeView(crumbs);
+ }
+ crumbHolder.addView(crumbs);
+ TextView name = (TextView) view.findViewById(R.id.group_name);
+ String groupName = mGroups.get(groupPosition);
+ if (groupName == null) {
+ groupName = mContext.getString(R.string.local_bookmarks);
+ }
+ name.setText(groupName);
+ return view;
+ }
+
+ public BreadCrumbView getBreadCrumbView(int groupPosition) {
+ BreadCrumbView crumbs = mBreadcrumbs.get(groupPosition);
+ if (crumbs == null) {
+ crumbs = (BreadCrumbView)
+ mInflater.inflate(R.layout.bookmarks_header, null);
+ crumbs.setController(BookmarkExpandableGridView.this);
+ crumbs.setUseBackButton(true);
+ crumbs.setMaxVisible(2);
+ String bookmarks = mContext.getString(R.string.bookmarks);
+ crumbs.pushView(bookmarks, false,
+ BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
+ crumbs.setTag(R.id.group_position, groupPosition);
+ mBreadcrumbs.put(groupPosition, crumbs);
+ }
+ return crumbs;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+ }
+
+ public static class BookmarkContextMenuInfo implements ContextMenuInfo {
+
+ private BookmarkContextMenuInfo(int childPosition, int groupPosition) {
+ this.childPosition = childPosition;
+ this.groupPosition = groupPosition;
+ }
+
+ public int childPosition;
+ public int groupPosition;
+ }
+
+}
diff --git a/src/com/android/browser/view/HorizontalScrollView.java b/src/com/android/browser/view/HorizontalScrollView.java
new file mode 100644
index 0000000..2da9058
--- /dev/null
+++ b/src/com/android/browser/view/HorizontalScrollView.java
@@ -0,0 +1,1453 @@
+/*
+ * 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.view;
+
+import com.android.internal.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.FocusFinder;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.animation.AnimationUtils;
+import android.widget.EdgeGlow;
+import android.widget.FrameLayout;
+import android.widget.OverScroller;
+
+import java.util.List;
+
+// copied from frameworks to allow for customizations
+public class HorizontalScrollView extends FrameLayout {
+
+ private static final int ANIMATED_SCROLL_GAP = 250;
+
+ private static final float MAX_SCROLL_FACTOR = 0.5f;
+
+
+ private long mLastScroll;
+
+ private final Rect mTempRect = new Rect();
+ protected OverScroller mScroller;
+ private EdgeGlow mEdgeGlowLeft;
+ private EdgeGlow mEdgeGlowRight;
+
+ /**
+ * Position of the last motion event.
+ */
+ private float mLastMotionX;
+
+ /**
+ * True when the layout has changed but the traversal has not come through yet.
+ * Ideally the view hierarchy would keep track of this for us.
+ */
+ private boolean mIsLayoutDirty = true;
+
+ /**
+ * The child to give focus to in the event that a child has requested focus while the
+ * layout is dirty. This prevents the scroll from being wrong if the child has not been
+ * laid out before requesting focus.
+ */
+ private View mChildToScrollTo = null;
+
+ /**
+ * True if the user is currently dragging this ScrollView around. This is
+ * not the same as 'is being flinged', which can be checked by
+ * mScroller.isFinished() (flinging begins when the user lifts his finger).
+ */
+ protected boolean mIsBeingDragged = false;
+
+ /**
+ * Determines speed during touch scrolling
+ */
+ private VelocityTracker mVelocityTracker;
+
+ /**
+ * When set to true, the scroll view measure its child to make it fill the currently
+ * visible area.
+ */
+ @ViewDebug.ExportedProperty(category = "layout")
+ private boolean mFillViewport;
+
+ /**
+ * Whether arrow scrolling is animated.
+ */
+ private boolean mSmoothScrollingEnabled = true;
+
+ private int mTouchSlop;
+ private int mMinimumVelocity;
+ private int mMaximumVelocity;
+
+ private int mOverscrollDistance;
+ private int mOverflingDistance;
+
+ /**
+ * ID of the active pointer. This is used to retain consistency during
+ * drags/flings if multiple pointers are used.
+ */
+ private int mActivePointerId = INVALID_POINTER;
+
+ /**
+ * Sentinel value for no current active pointer.
+ * Used by {@link #mActivePointerId}.
+ */
+ private static final int INVALID_POINTER = -1;
+
+ public HorizontalScrollView(Context context) {
+ this(context, null);
+ }
+
+ public HorizontalScrollView(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.horizontalScrollViewStyle);
+ }
+
+ public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initScrollView();
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ android.R.styleable.HorizontalScrollView, defStyle, 0);
+
+ setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
+
+ a.recycle();
+ }
+
+ @Override
+ protected float getLeftFadingEdgeStrength() {
+ return 0.0f;
+ }
+
+ @Override
+ protected float getRightFadingEdgeStrength() {
+ return 0.0f;
+ }
+
+ /**
+ * @return The maximum amount this scroll view will scroll in response to
+ * an arrow event.
+ */
+ public int getMaxScrollAmount() {
+ return (int) (MAX_SCROLL_FACTOR * (mRight - mLeft));
+ }
+
+
+ private void initScrollView() {
+ mScroller = new OverScroller(getContext());
+ setFocusable(true);
+ setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+ setWillNotDraw(false);
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+ mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mOverscrollDistance = configuration.getScaledOverscrollDistance();
+ mOverflingDistance = configuration.getScaledOverflingDistance();
+ }
+
+ @Override
+ public void addView(View child) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("HorizontalScrollView can host only one direct child");
+ }
+
+ super.addView(child);
+ }
+
+ @Override
+ public void addView(View child, int index) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("HorizontalScrollView can host only one direct child");
+ }
+
+ super.addView(child, index);
+ }
+
+ @Override
+ public void addView(View child, ViewGroup.LayoutParams params) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("HorizontalScrollView can host only one direct child");
+ }
+
+ super.addView(child, params);
+ }
+
+ @Override
+ public void addView(View child, int index, ViewGroup.LayoutParams params) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("HorizontalScrollView can host only one direct child");
+ }
+
+ super.addView(child, index, params);
+ }
+
+ /**
+ * @return Returns true this HorizontalScrollView can be scrolled
+ */
+ private boolean canScroll() {
+ View child = getChildAt(0);
+ if (child != null) {
+ int childWidth = child.getWidth();
+ return getWidth() < childWidth + mPaddingLeft + mPaddingRight ;
+ }
+ return false;
+ }
+
+ /**
+ * Indicates whether this HorizontalScrollView's content is stretched to
+ * fill the viewport.
+ *
+ * @return True if the content fills the viewport, false otherwise.
+ *
+ * @attr ref android.R.styleable#HorizontalScrollView_fillViewport
+ */
+ public boolean isFillViewport() {
+ return mFillViewport;
+ }
+
+ /**
+ * Indicates this HorizontalScrollView whether it should stretch its content width
+ * to fill the viewport or not.
+ *
+ * @param fillViewport True to stretch the content's width to the viewport's
+ * boundaries, false otherwise.
+ *
+ * @attr ref android.R.styleable#HorizontalScrollView_fillViewport
+ */
+ public void setFillViewport(boolean fillViewport) {
+ if (fillViewport != mFillViewport) {
+ mFillViewport = fillViewport;
+ requestLayout();
+ }
+ }
+
+ /**
+ * @return Whether arrow scrolling will animate its transition.
+ */
+ public boolean isSmoothScrollingEnabled() {
+ return mSmoothScrollingEnabled;
+ }
+
+ /**
+ * Set whether arrow scrolling will animate its transition.
+ * @param smoothScrollingEnabled whether arrow scrolling will animate its transition
+ */
+ public void setSmoothScrollingEnabled(boolean smoothScrollingEnabled) {
+ mSmoothScrollingEnabled = smoothScrollingEnabled;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ if (!mFillViewport) {
+ return;
+ }
+
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ if (widthMode == MeasureSpec.UNSPECIFIED) {
+ return;
+ }
+
+ if (getChildCount() > 0) {
+ final View child = getChildAt(0);
+ int width = getMeasuredWidth();
+ if (child.getMeasuredWidth() < width) {
+ final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop
+ + mPaddingBottom, lp.height);
+ width -= mPaddingLeft;
+ width -= mPaddingRight;
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ // Let the focused view and/or our descendants get the key first
+ return super.dispatchKeyEvent(event) || executeKeyEvent(event);
+ }
+
+ /**
+ * You can call this function yourself to have the scroll view perform
+ * scrolling from a key event, just as if the event had been dispatched to
+ * it by the view hierarchy.
+ *
+ * @param event The key event to execute.
+ * @return Return true if the event was handled, else false.
+ */
+ public boolean executeKeyEvent(KeyEvent event) {
+ mTempRect.setEmpty();
+
+ if (!canScroll()) {
+ if (isFocused()) {
+ View currentFocused = findFocus();
+ if (currentFocused == this) currentFocused = null;
+ View nextFocused = FocusFinder.getInstance().findNextFocus(this,
+ currentFocused, View.FOCUS_RIGHT);
+ return nextFocused != null && nextFocused != this &&
+ nextFocused.requestFocus(View.FOCUS_RIGHT);
+ }
+ return false;
+ }
+
+ boolean handled = false;
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (!event.isAltPressed()) {
+ handled = arrowScroll(View.FOCUS_LEFT);
+ } else {
+ handled = fullScroll(View.FOCUS_LEFT);
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (!event.isAltPressed()) {
+ handled = arrowScroll(View.FOCUS_RIGHT);
+ } else {
+ handled = fullScroll(View.FOCUS_RIGHT);
+ }
+ break;
+ case KeyEvent.KEYCODE_SPACE:
+ pageScroll(event.isShiftPressed() ? View.FOCUS_LEFT : View.FOCUS_RIGHT);
+ break;
+ }
+ }
+
+ return handled;
+ }
+
+ private boolean inChild(int x, int y) {
+ if (getChildCount() > 0) {
+ final int scrollX = mScrollX;
+ final View child = getChildAt(0);
+ return !(y < child.getTop()
+ || y >= child.getBottom()
+ || x < child.getLeft() - scrollX
+ || x >= child.getRight() - scrollX);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ /*
+ * This method JUST determines whether we want to intercept the motion.
+ * If we return true, onMotionEvent will be called and we do the actual
+ * scrolling there.
+ */
+
+ /*
+ * Shortcut the most recurring case: the user is in the dragging
+ * state and he is moving his finger. We want to intercept this
+ * motion.
+ */
+ final int action = ev.getAction();
+ if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
+ return true;
+ }
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
+ /*
+ * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+ * whether the user has moved far enough from his original down touch.
+ */
+
+ /*
+ * Locally do absolute value. mLastMotionX is set to the x value
+ * of the down event.
+ */
+ final int activePointerId = mActivePointerId;
+ if (activePointerId == INVALID_POINTER) {
+ // If we don't have a valid id, the touch down wasn't on content.
+ break;
+ }
+
+ final int pointerIndex = ev.findPointerIndex(activePointerId);
+ final float x = ev.getX(pointerIndex);
+ final int xDiff = (int) Math.abs(x - mLastMotionX);
+ if (xDiff > mTouchSlop) {
+ mIsBeingDragged = true;
+ mLastMotionX = x;
+ if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_DOWN: {
+ final float x = ev.getX();
+ if (!inChild((int) x, (int) ev.getY())) {
+ mIsBeingDragged = false;
+ break;
+ }
+
+ /*
+ * Remember location of down touch.
+ * ACTION_DOWN always refers to pointer index 0.
+ */
+ mLastMotionX = x;
+ mActivePointerId = ev.getPointerId(0);
+
+ /*
+ * If being flinged and user touches the screen, initiate drag;
+ * otherwise don't. mScroller.isFinished should be false when
+ * being flinged.
+ */
+ mIsBeingDragged = !mScroller.isFinished();
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ /* Release the drag */
+ mIsBeingDragged = false;
+ mActivePointerId = INVALID_POINTER;
+ if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
+ invalidate();
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ final int index = ev.getActionIndex();
+ mLastMotionX = ev.getX(index);
+ mActivePointerId = ev.getPointerId(index);
+ break;
+ }
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
+ break;
+ }
+
+ /*
+ * The only time we want to intercept motion events is if we are in the
+ * drag mode.
+ */
+ return mIsBeingDragged;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+
+ if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
+ // Don't handle edge touches immediately -- they may actually belong to one of our
+ // descendants.
+ return false;
+ }
+
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
+
+ /*
+ * If being flinged and user touches, stop the fling. isFinished
+ * will be false if being flinged.
+ */
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+
+ // Remember where the motion event started
+ mLastMotionX = ev.getX();
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ }
+ case MotionEvent.ACTION_MOVE:
+ if (mIsBeingDragged) {
+ // Scroll to follow the motion event
+ final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(activePointerIndex);
+ final int deltaX = (int) (mLastMotionX - x);
+ mLastMotionX = x;
+
+ final int oldX = mScrollX;
+ final int oldY = mScrollY;
+ final int range = getScrollRange();
+ if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
+ mOverscrollDistance, 0, true)) {
+ // Break our velocity if we hit a scroll barrier.
+ mVelocityTracker.clear();
+ }
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+
+ final int overscrollMode = getOverScrollMode();
+ if (overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
+ final int pulledToX = oldX + deltaX;
+ if (pulledToX < 0) {
+ mEdgeGlowLeft.onPull((float) deltaX / getWidth());
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.onRelease();
+ }
+ } else if (pulledToX > range) {
+ mEdgeGlowRight.onPull((float) deltaX / getWidth());
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.onRelease();
+ }
+ }
+ if (mEdgeGlowLeft != null
+ && (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) {
+ invalidate();
+ }
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mIsBeingDragged) {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
+
+ if (getChildCount() > 0) {
+ if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+ fling(-initialVelocity);
+ } else {
+ final int right = getScrollRange();
+ if (mScroller.springBack(mScrollX, mScrollY, 0, right, 0, 0)) {
+ invalidate();
+ }
+ }
+ }
+
+ mActivePointerId = INVALID_POINTER;
+ mIsBeingDragged = false;
+
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ if (mEdgeGlowLeft != null) {
+ mEdgeGlowLeft.onRelease();
+ mEdgeGlowRight.onRelease();
+ }
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ if (mIsBeingDragged && getChildCount() > 0) {
+ if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
+ invalidate();
+ }
+ mActivePointerId = INVALID_POINTER;
+ mIsBeingDragged = false;
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ if (mEdgeGlowLeft != null) {
+ mEdgeGlowLeft.onRelease();
+ mEdgeGlowRight.onRelease();
+ }
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
+ }
+ return true;
+ }
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionX = ev.getX(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ if (!mIsBeingDragged) {
+ final float hscroll;
+ if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+ hscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ } else {
+ hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ }
+ if (hscroll != 0) {
+ final int delta = (int) (hscroll * getHorizontalScrollFactor());
+ final int range = getScrollRange();
+ int oldScrollX = mScrollX;
+ int newScrollX = oldScrollX + delta;
+ if (newScrollX < 0) {
+ newScrollX = 0;
+ } else if (newScrollX > range) {
+ newScrollX = range;
+ }
+ if (newScrollX != oldScrollX) {
+ super.scrollTo(newScrollX, mScrollY);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ protected void onOverScrolled(int scrollX, int scrollY,
+ boolean clampedX, boolean clampedY) {
+ // Treat animating scrolls differently; see #computeScroll() for why.
+ if (!mScroller.isFinished()) {
+ mScrollX = scrollX;
+ mScrollY = scrollY;
+ invalidateParentIfNeeded();
+ if (clampedX) {
+ mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
+ }
+ } else {
+ super.scrollTo(scrollX, scrollY);
+ }
+ awakenScrollBars();
+ }
+
+ private int getScrollRange() {
+ int scrollRange = 0;
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ scrollRange = Math.max(0,
+ child.getWidth() - (getWidth() - mPaddingLeft - mPaddingRight));
+ }
+ return scrollRange;
+ }
+
+ /**
+ * <p>
+ * Finds the next focusable component that fits in this View's bounds
+ * (excluding fading edges) pretending that this View's left is located at
+ * the parameter left.
+ * </p>
+ *
+ * @param leftFocus look for a candidate is the one at the left of the bounds
+ * if leftFocus is true, or at the right of the bounds if leftFocus
+ * is false
+ * @param left the left offset of the bounds in which a focusable must be
+ * found (the fading edge is assumed to start at this position)
+ * @param preferredFocusable the View that has highest priority and will be
+ * returned if it is within my bounds (null is valid)
+ * @return the next focusable component in the bounds or null if none can be found
+ */
+ private View findFocusableViewInMyBounds(final boolean leftFocus,
+ final int left, View preferredFocusable) {
+ /*
+ * The fading edge's transparent side should be considered for focus
+ * since it's mostly visible, so we divide the actual fading edge length
+ * by 2.
+ */
+ final int fadingEdgeLength = getHorizontalFadingEdgeLength() / 2;
+ final int leftWithoutFadingEdge = left + fadingEdgeLength;
+ final int rightWithoutFadingEdge = left + getWidth() - fadingEdgeLength;
+
+ if ((preferredFocusable != null)
+ && (preferredFocusable.getLeft() < rightWithoutFadingEdge)
+ && (preferredFocusable.getRight() > leftWithoutFadingEdge)) {
+ return preferredFocusable;
+ }
+
+ return findFocusableViewInBounds(leftFocus, leftWithoutFadingEdge,
+ rightWithoutFadingEdge);
+ }
+
+ /**
+ * <p>
+ * Finds the next focusable component that fits in the specified bounds.
+ * </p>
+ *
+ * @param leftFocus look for a candidate is the one at the left of the bounds
+ * if leftFocus is true, or at the right of the bounds if
+ * leftFocus is false
+ * @param left the left offset of the bounds in which a focusable must be
+ * found
+ * @param right the right offset of the bounds in which a focusable must
+ * be found
+ * @return the next focusable component in the bounds or null if none can
+ * be found
+ */
+ private View findFocusableViewInBounds(boolean leftFocus, int left, int right) {
+
+ List<View> focusables = getFocusables(View.FOCUS_FORWARD);
+ View focusCandidate = null;
+
+ /*
+ * A fully contained focusable is one where its left is below the bound's
+ * left, and its right is above the bound's right. A partially
+ * contained focusable is one where some part of it is within the
+ * bounds, but it also has some part that is not within bounds. A fully contained
+ * focusable is preferred to a partially contained focusable.
+ */
+ boolean foundFullyContainedFocusable = false;
+
+ int count = focusables.size();
+ for (int i = 0; i < count; i++) {
+ View view = focusables.get(i);
+ int viewLeft = view.getLeft();
+ int viewRight = view.getRight();
+
+ if (left < viewRight && viewLeft < right) {
+ /*
+ * the focusable is in the target area, it is a candidate for
+ * focusing
+ */
+
+ final boolean viewIsFullyContained = (left < viewLeft) &&
+ (viewRight < right);
+
+ if (focusCandidate == null) {
+ /* No candidate, take this one */
+ focusCandidate = view;
+ foundFullyContainedFocusable = viewIsFullyContained;
+ } else {
+ final boolean viewIsCloserToBoundary =
+ (leftFocus && viewLeft < focusCandidate.getLeft()) ||
+ (!leftFocus && viewRight > focusCandidate.getRight());
+
+ if (foundFullyContainedFocusable) {
+ if (viewIsFullyContained && viewIsCloserToBoundary) {
+ /*
+ * We're dealing with only fully contained views, so
+ * it has to be closer to the boundary to beat our
+ * candidate
+ */
+ focusCandidate = view;
+ }
+ } else {
+ if (viewIsFullyContained) {
+ /* Any fully contained view beats a partially contained view */
+ focusCandidate = view;
+ foundFullyContainedFocusable = true;
+ } else if (viewIsCloserToBoundary) {
+ /*
+ * Partially contained view beats another partially
+ * contained view if it's closer
+ */
+ focusCandidate = view;
+ }
+ }
+ }
+ }
+ }
+
+ return focusCandidate;
+ }
+
+ /**
+ * <p>Handles scrolling in response to a "page up/down" shortcut press. This
+ * method will scroll the view by one page left or right and give the focus
+ * to the leftmost/rightmost component in the new visible area. If no
+ * component is a good candidate for focus, this scrollview reclaims the
+ * focus.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_LEFT}
+ * to go one page left or {@link android.view.View#FOCUS_RIGHT}
+ * to go one page right
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ public boolean pageScroll(int direction) {
+ boolean right = direction == View.FOCUS_RIGHT;
+ int width = getWidth();
+
+ if (right) {
+ mTempRect.left = getScrollX() + width;
+ int count = getChildCount();
+ if (count > 0) {
+ View view = getChildAt(0);
+ if (mTempRect.left + width > view.getRight()) {
+ mTempRect.left = view.getRight() - width;
+ }
+ }
+ } else {
+ mTempRect.left = getScrollX() - width;
+ if (mTempRect.left < 0) {
+ mTempRect.left = 0;
+ }
+ }
+ mTempRect.right = mTempRect.left + width;
+
+ return scrollAndFocus(direction, mTempRect.left, mTempRect.right);
+ }
+
+ /**
+ * <p>Handles scrolling in response to a "home/end" shortcut press. This
+ * method will scroll the view to the left or right and give the focus
+ * to the leftmost/rightmost component in the new visible area. If no
+ * component is a good candidate for focus, this scrollview reclaims the
+ * focus.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_LEFT}
+ * to go the left of the view or {@link android.view.View#FOCUS_RIGHT}
+ * to go the right
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ public boolean fullScroll(int direction) {
+ boolean right = direction == View.FOCUS_RIGHT;
+ int width = getWidth();
+
+ mTempRect.left = 0;
+ mTempRect.right = width;
+
+ if (right) {
+ int count = getChildCount();
+ if (count > 0) {
+ View view = getChildAt(0);
+ mTempRect.right = view.getRight();
+ mTempRect.left = mTempRect.right - width;
+ }
+ }
+
+ return scrollAndFocus(direction, mTempRect.left, mTempRect.right);
+ }
+
+ /**
+ * <p>Scrolls the view to make the area defined by <code>left</code> and
+ * <code>right</code> visible. This method attempts to give the focus
+ * to a component visible in this area. If no component can be focused in
+ * the new visible area, the focus is reclaimed by this scrollview.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_LEFT}
+ * to go left {@link android.view.View#FOCUS_RIGHT} to right
+ * @param left the left offset of the new area to be made visible
+ * @param right the right offset of the new area to be made visible
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ private boolean scrollAndFocus(int direction, int left, int right) {
+ boolean handled = true;
+
+ int width = getWidth();
+ int containerLeft = getScrollX();
+ int containerRight = containerLeft + width;
+ boolean goLeft = direction == View.FOCUS_LEFT;
+
+ View newFocused = findFocusableViewInBounds(goLeft, left, right);
+ if (newFocused == null) {
+ newFocused = this;
+ }
+
+ if (left >= containerLeft && right <= containerRight) {
+ handled = false;
+ } else {
+ int delta = goLeft ? (left - containerLeft) : (right - containerRight);
+ doScrollX(delta);
+ }
+
+ if (newFocused != findFocus()) newFocused.requestFocus(direction);
+
+ return handled;
+ }
+
+ /**
+ * Handle scrolling in response to a left or right arrow click.
+ *
+ * @param direction The direction corresponding to the arrow key that was
+ * pressed
+ * @return True if we consumed the event, false otherwise
+ */
+ public boolean arrowScroll(int direction) {
+
+ View currentFocused = findFocus();
+ if (currentFocused == this) currentFocused = null;
+
+ View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
+
+ final int maxJump = getMaxScrollAmount();
+
+ if (nextFocused != null && isWithinDeltaOfScreen(nextFocused, maxJump)) {
+ nextFocused.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(nextFocused, mTempRect);
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+ doScrollX(scrollDelta);
+ nextFocused.requestFocus(direction);
+ } else {
+ // no new focus
+ int scrollDelta = maxJump;
+
+ if (direction == View.FOCUS_LEFT && getScrollX() < scrollDelta) {
+ scrollDelta = getScrollX();
+ } else if (direction == View.FOCUS_RIGHT && getChildCount() > 0) {
+
+ int daRight = getChildAt(0).getRight();
+
+ int screenRight = getScrollX() + getWidth();
+
+ if (daRight - screenRight < maxJump) {
+ scrollDelta = daRight - screenRight;
+ }
+ }
+ if (scrollDelta == 0) {
+ return false;
+ }
+ doScrollX(direction == View.FOCUS_RIGHT ? scrollDelta : -scrollDelta);
+ }
+
+ if (currentFocused != null && currentFocused.isFocused()
+ && isOffScreen(currentFocused)) {
+ // previously focused item still has focus and is off screen, give
+ // it up (take it back to ourselves)
+ // (also, need to temporarily force FOCUS_BEFORE_DESCENDANTS so we are
+ // sure to
+ // get it)
+ final int descendantFocusability = getDescendantFocusability(); // save
+ setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+ requestFocus();
+ setDescendantFocusability(descendantFocusability); // restore
+ }
+ return true;
+ }
+
+ /**
+ * @return whether the descendant of this scroll view is scrolled off
+ * screen.
+ */
+ private boolean isOffScreen(View descendant) {
+ return !isWithinDeltaOfScreen(descendant, 0);
+ }
+
+ /**
+ * @return whether the descendant of this scroll view is within delta
+ * pixels of being on the screen.
+ */
+ private boolean isWithinDeltaOfScreen(View descendant, int delta) {
+ descendant.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(descendant, mTempRect);
+
+ return (mTempRect.right + delta) >= getScrollX()
+ && (mTempRect.left - delta) <= (getScrollX() + getWidth());
+ }
+
+ /**
+ * Smooth scroll by a X delta
+ *
+ * @param delta the number of pixels to scroll by on the X axis
+ */
+ private void doScrollX(int delta) {
+ if (delta != 0) {
+ if (mSmoothScrollingEnabled) {
+ smoothScrollBy(delta, 0);
+ } else {
+ scrollBy(delta, 0);
+ }
+ }
+ }
+
+ /**
+ * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
+ *
+ * @param dx the number of pixels to scroll by on the X axis
+ * @param dy the number of pixels to scroll by on the Y axis
+ */
+ public final void smoothScrollBy(int dx, int dy) {
+ if (getChildCount() == 0) {
+ // Nothing to do.
+ return;
+ }
+ long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
+ if (duration > ANIMATED_SCROLL_GAP) {
+ final int width = getWidth() - mPaddingRight - mPaddingLeft;
+ final int right = getChildAt(0).getWidth();
+ final int maxX = Math.max(0, right - width);
+ final int scrollX = mScrollX;
+ dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
+
+ mScroller.startScroll(scrollX, mScrollY, dx, 0);
+ invalidate();
+ } else {
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+ scrollBy(dx, dy);
+ }
+ mLastScroll = AnimationUtils.currentAnimationTimeMillis();
+ }
+
+ /**
+ * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
+ *
+ * @param x the position where to scroll on the X axis
+ * @param y the position where to scroll on the Y axis
+ */
+ public final void smoothScrollTo(int x, int y) {
+ smoothScrollBy(x - mScrollX, y - mScrollY);
+ }
+
+ /**
+ * <p>The scroll range of a scroll view is the overall width of all of its
+ * children.</p>
+ */
+ @Override
+ protected int computeHorizontalScrollRange() {
+ final int count = getChildCount();
+ final int contentWidth = getWidth() - mPaddingLeft - mPaddingRight;
+ if (count == 0) {
+ return contentWidth;
+ }
+
+ int scrollRange = getChildAt(0).getRight();
+ final int scrollX = mScrollX;
+ final int overscrollRight = Math.max(0, scrollRange - contentWidth);
+ if (scrollX < 0) {
+ scrollRange -= scrollX;
+ } else if (scrollX > overscrollRight) {
+ scrollRange += scrollX - overscrollRight;
+ }
+
+ return scrollRange;
+ }
+
+ @Override
+ protected int computeHorizontalScrollOffset() {
+ return Math.max(0, super.computeHorizontalScrollOffset());
+ }
+
+ @Override
+ protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
+ ViewGroup.LayoutParams lp = child.getLayoutParams();
+
+ int childWidthMeasureSpec;
+ int childHeightMeasureSpec;
+
+ childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingTop
+ + mPaddingBottom, lp.height);
+
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ @Override
+ protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
+ int parentHeightMeasureSpec, int heightUsed) {
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
+ mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+ + heightUsed, lp.height);
+ final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ @Override
+ public void computeScroll() {
+ if (mScroller.computeScrollOffset()) {
+ // This is called at drawing time by ViewGroup. We don't want to
+ // re-show the scrollbars at this point, which scrollTo will do,
+ // so we replicate most of scrollTo here.
+ //
+ // It's a little odd to call onScrollChanged from inside the drawing.
+ //
+ // It is, except when you remember that computeScroll() is used to
+ // animate scrolling. So unless we want to defer the onScrollChanged()
+ // until the end of the animated scrolling, we don't really have a
+ // choice here.
+ //
+ // I agree. The alternative, which I think would be worse, is to post
+ // something and tell the subclasses later. This is bad because there
+ // will be a window where mScrollX/Y is different from what the app
+ // thinks it is.
+ //
+ int oldX = mScrollX;
+ int oldY = mScrollY;
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+
+ if (oldX != x || oldY != y) {
+ overScrollBy(x - oldX, y - oldY, oldX, oldY, getScrollRange(), 0,
+ mOverflingDistance, 0, false);
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+
+ final int range = getScrollRange();
+ final int overscrollMode = getOverScrollMode();
+ if (overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
+ if (x < 0 && oldX >= 0) {
+ mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
+ } else if (x > range && oldX <= range) {
+ mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
+ }
+ }
+ }
+ awakenScrollBars();
+
+ // Keep on drawing until the animation has finished.
+ postInvalidate();
+ }
+ }
+
+ /**
+ * Scrolls the view to the given child.
+ *
+ * @param child the View to scroll to
+ */
+ private void scrollToChild(View child) {
+ child.getDrawingRect(mTempRect);
+
+ /* Offset from child's local coordinates to ScrollView coordinates */
+ offsetDescendantRectToMyCoords(child, mTempRect);
+
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+
+ if (scrollDelta != 0) {
+ scrollBy(scrollDelta, 0);
+ }
+ }
+
+ /**
+ * If rect is off screen, scroll just enough to get it (or at least the
+ * first screen size chunk of it) on screen.
+ *
+ * @param rect The rectangle.
+ * @param immediate True to scroll immediately without animation
+ * @return true if scrolling was performed
+ */
+ protected boolean scrollToChildRect(Rect rect, boolean immediate) {
+ final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
+ final boolean scroll = delta != 0;
+ if (scroll) {
+ if (immediate) {
+ scrollBy(delta, 0);
+ } else {
+ smoothScrollBy(delta, 0);
+ }
+ }
+ return scroll;
+ }
+
+ /**
+ * Compute the amount to scroll in the X direction in order to get
+ * a rectangle completely on the screen (or, if taller than the screen,
+ * at least the first screen size chunk of it).
+ *
+ * @param rect The rect.
+ * @return The scroll delta.
+ */
+ protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
+ if (getChildCount() == 0) return 0;
+
+ int width = getWidth();
+ int screenLeft = getScrollX();
+ int screenRight = screenLeft + width;
+
+ int fadingEdge = getHorizontalFadingEdgeLength();
+
+ // leave room for left fading edge as long as rect isn't at very left
+ if (rect.left > 0) {
+ screenLeft += fadingEdge;
+ }
+
+ // leave room for right fading edge as long as rect isn't at very right
+ if (rect.right < getChildAt(0).getWidth()) {
+ screenRight -= fadingEdge;
+ }
+
+ int scrollXDelta = 0;
+
+ if (rect.right > screenRight && rect.left > screenLeft) {
+ // need to move right to get it in view: move right just enough so
+ // that the entire rectangle is in view (or at least the first
+ // screen size chunk).
+
+ if (rect.width() > width) {
+ // just enough to get screen size chunk on
+ scrollXDelta += (rect.left - screenLeft);
+ } else {
+ // get entire rect at right of screen
+ scrollXDelta += (rect.right - screenRight);
+ }
+
+ // make sure we aren't scrolling beyond the end of our content
+ int right = getChildAt(0).getRight();
+ int distanceToRight = right - screenRight;
+ scrollXDelta = Math.min(scrollXDelta, distanceToRight);
+
+ } else if (rect.left < screenLeft && rect.right < screenRight) {
+ // need to move right to get it in view: move right just enough so that
+ // entire rectangle is in view (or at least the first screen
+ // size chunk of it).
+
+ if (rect.width() > width) {
+ // screen size chunk
+ scrollXDelta -= (screenRight - rect.right);
+ } else {
+ // entire rect at left
+ scrollXDelta -= (screenLeft - rect.left);
+ }
+
+ // make sure we aren't scrolling any further than the left our content
+ scrollXDelta = Math.max(scrollXDelta, -getScrollX());
+ }
+ return scrollXDelta;
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ if (!mIsLayoutDirty) {
+ scrollToChild(focused);
+ } else {
+ // The child may not be laid out yet, we can't compute the scroll yet
+ mChildToScrollTo = focused;
+ }
+ super.requestChildFocus(child, focused);
+ }
+
+
+ /**
+ * When looking for focus in children of a scroll view, need to be a little
+ * more careful not to give focus to something that is scrolled off screen.
+ *
+ * This is more expensive than the default {@link android.view.ViewGroup}
+ * implementation, otherwise this behavior might have been made the default.
+ */
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction,
+ Rect previouslyFocusedRect) {
+
+ // convert from forward / backward notation to up / down / left / right
+ // (ugh).
+ if (direction == View.FOCUS_FORWARD) {
+ direction = View.FOCUS_RIGHT;
+ } else if (direction == View.FOCUS_BACKWARD) {
+ direction = View.FOCUS_LEFT;
+ }
+
+ final View nextFocus = previouslyFocusedRect == null ?
+ FocusFinder.getInstance().findNextFocus(this, null, direction) :
+ FocusFinder.getInstance().findNextFocusFromRect(this,
+ previouslyFocusedRect, direction);
+
+ if (nextFocus == null) {
+ return false;
+ }
+
+ if (isOffScreen(nextFocus)) {
+ return false;
+ }
+
+ return nextFocus.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ @Override
+ public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
+ boolean immediate) {
+ // offset into coordinate space of this scroll view
+ rectangle.offset(child.getLeft() - child.getScrollX(),
+ child.getTop() - child.getScrollY());
+
+ return scrollToChildRect(rectangle, immediate);
+ }
+
+ @Override
+ public void requestLayout() {
+ mIsLayoutDirty = true;
+ super.requestLayout();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ mIsLayoutDirty = false;
+ // Give a child focus if it needs it
+ if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
+ scrollToChild(mChildToScrollTo);
+ }
+ mChildToScrollTo = null;
+
+ // Calling this with the present values causes it to re-clam them
+ scrollTo(mScrollX, mScrollY);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ View currentFocused = findFocus();
+ if (null == currentFocused || this == currentFocused)
+ return;
+
+ final int maxJump = mRight - mLeft;
+
+ if (isWithinDeltaOfScreen(currentFocused, maxJump)) {
+ currentFocused.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(currentFocused, mTempRect);
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+ doScrollX(scrollDelta);
+ }
+ }
+
+ /**
+ * Return true if child is an descendant of parent, (or equal to the parent).
+ */
+ private boolean isViewDescendantOf(View child, View parent) {
+ if (child == parent) {
+ return true;
+ }
+
+ final ViewParent theParent = child.getParent();
+ return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
+ }
+
+ /**
+ * Fling the scroll view
+ *
+ * @param velocityX The initial velocity in the X direction. Positive
+ * numbers mean that the finger/curor is moving down the screen,
+ * which means we want to scroll towards the left.
+ */
+ public void fling(int velocityX) {
+ if (getChildCount() > 0) {
+ int width = getWidth() - mPaddingRight - mPaddingLeft;
+ int right = getChildAt(0).getWidth();
+
+ mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
+ Math.max(0, right - width), 0, 0, width/2, 0);
+
+ final boolean movingRight = velocityX > 0;
+
+ View currentFocused = findFocus();
+ View newFocused = findFocusableViewInMyBounds(movingRight,
+ mScroller.getFinalX(), currentFocused);
+
+ if (newFocused == null) {
+ newFocused = this;
+ }
+
+ if (newFocused != currentFocused) {
+ newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
+ }
+
+ invalidate();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This version also clamps the scrolling to the bounds of our child.
+ */
+ @Override
+ public void scrollTo(int x, int y) {
+ // we rely on the fact the View.scrollBy calls scrollTo.
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ x = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
+ y = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
+ if (x != mScrollX || y != mScrollY) {
+ super.scrollTo(x, y);
+ }
+ }
+ }
+
+ @Override
+ public void setOverScrollMode(int mode) {
+ if (mode != OVER_SCROLL_NEVER) {
+ if (mEdgeGlowLeft == null) {
+ Context context = getContext();
+ final Resources res = context.getResources();
+ final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
+ final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
+ mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
+ mEdgeGlowRight = new EdgeGlow(context, edge, glow);
+ }
+ } else {
+ mEdgeGlowLeft = null;
+ mEdgeGlowRight = null;
+ }
+ super.setOverScrollMode(mode);
+ }
+
+ @SuppressWarnings({"SuspiciousNameCombination"})
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ if (mEdgeGlowLeft != null) {
+ final int scrollX = mScrollX;
+ if (!mEdgeGlowLeft.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int height = getHeight() - mPaddingTop - mPaddingBottom;
+
+ canvas.rotate(270);
+ canvas.translate(-height + mPaddingTop, Math.min(0, scrollX));
+ mEdgeGlowLeft.setSize(height, getWidth());
+ if (mEdgeGlowLeft.draw(canvas)) {
+ invalidate();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int width = getWidth();
+ final int height = getHeight() - mPaddingTop - mPaddingBottom;
+
+ canvas.rotate(90);
+ canvas.translate(-mPaddingTop,
+ -(Math.max(getScrollRange(), scrollX) + width));
+ mEdgeGlowRight.setSize(height, width);
+ if (mEdgeGlowRight.draw(canvas)) {
+ invalidate();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ }
+ }
+
+ private int clamp(int n, int my, int child) {
+ if (my >= child || n < 0) {
+ return 0;
+ }
+ if ((my + n) > child) {
+ return child - my;
+ }
+ return n;
+ }
+}
diff --git a/src/com/android/browser/view/ScrollView.java b/src/com/android/browser/view/ScrollView.java
new file mode 100644
index 0000000..ab09a8c
--- /dev/null
+++ b/src/com/android/browser/view/ScrollView.java
@@ -0,0 +1,1538 @@
+/*
+ * Copyright (C) 2011 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.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.StrictMode;
+import android.util.AttributeSet;
+import android.view.FocusFinder;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.animation.AnimationUtils;
+import android.widget.EdgeGlow;
+import android.widget.FrameLayout;
+import android.widget.OverScroller;
+
+import com.android.internal.R;
+
+import java.util.List;
+
+public class ScrollView extends FrameLayout {
+ static final int ANIMATED_SCROLL_GAP = 250;
+
+ static final float MAX_SCROLL_FACTOR = 0.5f;
+
+
+ private long mLastScroll;
+
+ private final Rect mTempRect = new Rect();
+ protected OverScroller mScroller;
+ private EdgeGlow mEdgeGlowTop;
+ private EdgeGlow mEdgeGlowBottom;
+
+ /**
+ * Position of the last motion event.
+ */
+ private float mLastMotionY;
+
+ /**
+ * True when the layout has changed but the traversal has not come through yet.
+ * Ideally the view hierarchy would keep track of this for us.
+ */
+ private boolean mIsLayoutDirty = true;
+
+ /**
+ * The child to give focus to in the event that a child has requested focus while the
+ * layout is dirty. This prevents the scroll from being wrong if the child has not been
+ * laid out before requesting focus.
+ */
+ private View mChildToScrollTo = null;
+
+ /**
+ * True if the user is currently dragging this ScrollView around. This is
+ * not the same as 'is being flinged', which can be checked by
+ * mScroller.isFinished() (flinging begins when the user lifts his finger).
+ */
+ protected boolean mIsBeingDragged = false;
+
+ /**
+ * Determines speed during touch scrolling
+ */
+ private VelocityTracker mVelocityTracker;
+
+ /**
+ * When set to true, the scroll view measure its child to make it fill the currently
+ * visible area.
+ */
+ @ViewDebug.ExportedProperty(category = "layout")
+ private boolean mFillViewport;
+
+ /**
+ * Whether arrow scrolling is animated.
+ */
+ private boolean mSmoothScrollingEnabled = true;
+
+ private int mTouchSlop;
+ private int mMinimumVelocity;
+ private int mMaximumVelocity;
+
+ private int mOverscrollDistance;
+ private int mOverflingDistance;
+
+ /**
+ * ID of the active pointer. This is used to retain consistency during
+ * drags/flings if multiple pointers are used.
+ */
+ private int mActivePointerId = INVALID_POINTER;
+
+ /**
+ * The StrictMode "critical time span" objects to catch animation
+ * stutters. Non-null when a time-sensitive animation is
+ * in-flight. Must call finish() on them when done animating.
+ * These are no-ops on user builds.
+ */
+ private StrictMode.Span mScrollStrictSpan = null; // aka "drag"
+ private StrictMode.Span mFlingStrictSpan = null;
+
+ /**
+ * Sentinel value for no current active pointer.
+ * Used by {@link #mActivePointerId}.
+ */
+ private static final int INVALID_POINTER = -1;
+
+ public ScrollView(Context context) {
+ this(context, null);
+ }
+
+ public ScrollView(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.scrollViewStyle);
+ }
+
+ public ScrollView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initScrollView();
+
+ TypedArray a =
+ context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ScrollView, defStyle, 0);
+
+ setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
+
+ a.recycle();
+ }
+
+ @Override
+ public boolean shouldDelayChildPressedState() {
+ return true;
+ }
+
+ @Override
+ protected float getTopFadingEdgeStrength() {
+ if (getChildCount() == 0) {
+ return 0.0f;
+ }
+
+ final int length = getVerticalFadingEdgeLength();
+ if (mScrollY < length) {
+ return mScrollY / (float) length;
+ }
+
+ return 1.0f;
+ }
+
+ @Override
+ protected float getBottomFadingEdgeStrength() {
+ if (getChildCount() == 0) {
+ return 0.0f;
+ }
+
+ final int length = getVerticalFadingEdgeLength();
+ final int bottomEdge = getHeight() - mPaddingBottom;
+ final int span = getChildAt(0).getBottom() - mScrollY - bottomEdge;
+ if (span < length) {
+ return span / (float) length;
+ }
+
+ return 1.0f;
+ }
+
+ /**
+ * @return The maximum amount this scroll view will scroll in response to
+ * an arrow event.
+ */
+ public int getMaxScrollAmount() {
+ return (int) (MAX_SCROLL_FACTOR * (mBottom - mTop));
+ }
+
+
+ private void initScrollView() {
+ mScroller = new OverScroller(getContext());
+ setFocusable(true);
+ setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+ setWillNotDraw(false);
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+ mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mOverscrollDistance = configuration.getScaledOverscrollDistance();
+ mOverflingDistance = configuration.getScaledOverflingDistance();
+ }
+
+ @Override
+ public void addView(View child) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("ScrollView can host only one direct child");
+ }
+
+ super.addView(child);
+ }
+
+ @Override
+ public void addView(View child, int index) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("ScrollView can host only one direct child");
+ }
+
+ super.addView(child, index);
+ }
+
+ @Override
+ public void addView(View child, ViewGroup.LayoutParams params) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("ScrollView can host only one direct child");
+ }
+
+ super.addView(child, params);
+ }
+
+ @Override
+ public void addView(View child, int index, ViewGroup.LayoutParams params) {
+ if (getChildCount() > 0) {
+ throw new IllegalStateException("ScrollView can host only one direct child");
+ }
+
+ super.addView(child, index, params);
+ }
+
+ /**
+ * @return Returns true this ScrollView can be scrolled
+ */
+ private boolean canScroll() {
+ View child = getChildAt(0);
+ if (child != null) {
+ int childHeight = child.getHeight();
+ return getHeight() < childHeight + mPaddingTop + mPaddingBottom;
+ }
+ return false;
+ }
+
+ /**
+ * Indicates whether this ScrollView's content is stretched to fill the viewport.
+ *
+ * @return True if the content fills the viewport, false otherwise.
+ *
+ * @attr ref android.R.styleable#ScrollView_fillViewport
+ */
+ public boolean isFillViewport() {
+ return mFillViewport;
+ }
+
+ /**
+ * Indicates this ScrollView whether it should stretch its content height to fill
+ * the viewport or not.
+ *
+ * @param fillViewport True to stretch the content's height to the viewport's
+ * boundaries, false otherwise.
+ *
+ * @attr ref android.R.styleable#ScrollView_fillViewport
+ */
+ public void setFillViewport(boolean fillViewport) {
+ if (fillViewport != mFillViewport) {
+ mFillViewport = fillViewport;
+ requestLayout();
+ }
+ }
+
+ /**
+ * @return Whether arrow scrolling will animate its transition.
+ */
+ public boolean isSmoothScrollingEnabled() {
+ return mSmoothScrollingEnabled;
+ }
+
+ /**
+ * Set whether arrow scrolling will animate its transition.
+ * @param smoothScrollingEnabled whether arrow scrolling will animate its transition
+ */
+ public void setSmoothScrollingEnabled(boolean smoothScrollingEnabled) {
+ mSmoothScrollingEnabled = smoothScrollingEnabled;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ if (!mFillViewport) {
+ return;
+ }
+
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ if (heightMode == MeasureSpec.UNSPECIFIED) {
+ return;
+ }
+
+ if (getChildCount() > 0) {
+ final View child = getChildAt(0);
+ int height = getMeasuredHeight();
+ if (child.getMeasuredHeight() < height) {
+ final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ mPaddingLeft + mPaddingRight, lp.width);
+ height -= mPaddingTop;
+ height -= mPaddingBottom;
+ int childHeightMeasureSpec =
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ // Let the focused view and/or our descendants get the key first
+ return super.dispatchKeyEvent(event) || executeKeyEvent(event);
+ }
+
+ /**
+ * You can call this function yourself to have the scroll view perform
+ * scrolling from a key event, just as if the event had been dispatched to
+ * it by the view hierarchy.
+ *
+ * @param event The key event to execute.
+ * @return Return true if the event was handled, else false.
+ */
+ public boolean executeKeyEvent(KeyEvent event) {
+ mTempRect.setEmpty();
+
+ if (!canScroll()) {
+ if (isFocused() && event.getKeyCode() != KeyEvent.KEYCODE_BACK) {
+ View currentFocused = findFocus();
+ if (currentFocused == this) currentFocused = null;
+ View nextFocused = FocusFinder.getInstance().findNextFocus(this,
+ currentFocused, View.FOCUS_DOWN);
+ return nextFocused != null
+ && nextFocused != this
+ && nextFocused.requestFocus(View.FOCUS_DOWN);
+ }
+ return false;
+ }
+
+ boolean handled = false;
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (!event.isAltPressed()) {
+ handled = arrowScroll(View.FOCUS_UP);
+ } else {
+ handled = fullScroll(View.FOCUS_UP);
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (!event.isAltPressed()) {
+ handled = arrowScroll(View.FOCUS_DOWN);
+ } else {
+ handled = fullScroll(View.FOCUS_DOWN);
+ }
+ break;
+ case KeyEvent.KEYCODE_SPACE:
+ pageScroll(event.isShiftPressed() ? View.FOCUS_UP : View.FOCUS_DOWN);
+ break;
+ }
+ }
+
+ return handled;
+ }
+
+ private boolean inChild(int x, int y) {
+ if (getChildCount() > 0) {
+ final int scrollY = mScrollY;
+ final View child = getChildAt(0);
+ return !(y < child.getTop() - scrollY
+ || y >= child.getBottom() - scrollY
+ || x < child.getLeft()
+ || x >= child.getRight());
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ /*
+ * This method JUST determines whether we want to intercept the motion.
+ * If we return true, onMotionEvent will be called and we do the actual
+ * scrolling there.
+ */
+
+ /*
+ * Shortcut the most recurring case: the user is in the dragging
+ * state and he is moving his finger. We want to intercept this
+ * motion.
+ */
+ final int action = ev.getAction();
+ if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
+ return true;
+ }
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
+ /*
+ * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+ * whether the user has moved far enough from his original down touch.
+ */
+
+ /*
+ * Locally do absolute value. mLastMotionY is set to the y value
+ * of the down event.
+ */
+ final int activePointerId = mActivePointerId;
+ if (activePointerId == INVALID_POINTER) {
+ // If we don't have a valid id, the touch down wasn't on content.
+ break;
+ }
+
+ final int pointerIndex = ev.findPointerIndex(activePointerId);
+ final float y = ev.getY(pointerIndex);
+ final int yDiff = (int) Math.abs(y - mLastMotionY);
+ if (yDiff > mTouchSlop) {
+ mIsBeingDragged = true;
+ mLastMotionY = y;
+ if (mScrollStrictSpan == null) {
+ mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
+ }
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_DOWN: {
+ final float y = ev.getY();
+ if (!inChild((int) ev.getX(), (int) y)) {
+ mIsBeingDragged = false;
+ break;
+ }
+
+ /*
+ * Remember location of down touch.
+ * ACTION_DOWN always refers to pointer index 0.
+ */
+ mLastMotionY = y;
+ mActivePointerId = ev.getPointerId(0);
+
+ /*
+ * If being flinged and user touches the screen, initiate drag;
+ * otherwise don't. mScroller.isFinished should be false when
+ * being flinged.
+ */
+ mIsBeingDragged = !mScroller.isFinished();
+ if (mIsBeingDragged && mScrollStrictSpan == null) {
+ mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ /* Release the drag */
+ mIsBeingDragged = false;
+ mActivePointerId = INVALID_POINTER;
+ if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
+ invalidate();
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
+ }
+
+ /*
+ * The only time we want to intercept motion events is if we are in the
+ * drag mode.
+ */
+ return mIsBeingDragged;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+
+ if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
+ // Don't handle edge touches immediately -- they may actually belong to one of our
+ // descendants.
+ return false;
+ }
+
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
+
+ /*
+ * If being flinged and user touches, stop the fling. isFinished
+ * will be false if being flinged.
+ */
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
+ }
+
+ // Remember where the motion event started
+ mLastMotionY = ev.getY();
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ }
+ case MotionEvent.ACTION_MOVE:
+ if (mIsBeingDragged) {
+ // Scroll to follow the motion event
+ final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float y = ev.getY(activePointerIndex);
+ final int deltaY = (int) (mLastMotionY - y);
+ mLastMotionY = y;
+
+ final int oldX = mScrollX;
+ final int oldY = mScrollY;
+ final int range = getScrollRange();
+ if (overScrollBy(0, deltaY, 0, mScrollY, 0, range,
+ 0, mOverscrollDistance, true)) {
+ // Break our velocity if we hit a scroll barrier.
+ mVelocityTracker.clear();
+ }
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+
+ final int overscrollMode = getOverScrollMode();
+ if (overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
+ final int pulledToY = oldY + deltaY;
+ if (pulledToY < 0) {
+ mEdgeGlowTop.onPull((float) deltaY / getHeight());
+ if (!mEdgeGlowBottom.isFinished()) {
+ mEdgeGlowBottom.onRelease();
+ }
+ } else if (pulledToY > range) {
+ mEdgeGlowBottom.onPull((float) deltaY / getHeight());
+ if (!mEdgeGlowTop.isFinished()) {
+ mEdgeGlowTop.onRelease();
+ }
+ }
+ if (mEdgeGlowTop != null
+ && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
+ invalidate();
+ }
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mIsBeingDragged) {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
+
+ if (getChildCount() > 0) {
+ if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+ fling(-initialVelocity);
+ } else {
+ final int bottom = getScrollRange();
+ if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, bottom)) {
+ invalidate();
+ }
+ }
+ }
+
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ if (mIsBeingDragged && getChildCount() > 0) {
+ if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
+ invalidate();
+ }
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ final int index = ev.getActionIndex();
+ final float y = ev.getY(index);
+ mLastMotionY = y;
+ mActivePointerId = ev.getPointerId(index);
+ break;
+ }
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
+ break;
+ }
+ return true;
+ }
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionY = ev.getY(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ if (!mIsBeingDragged) {
+ final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ if (vscroll != 0) {
+ final int delta = (int) (vscroll * getVerticalScrollFactor());
+ final int range = getScrollRange();
+ int oldScrollY = mScrollY;
+ int newScrollY = oldScrollY - delta;
+ if (newScrollY < 0) {
+ newScrollY = 0;
+ } else if (newScrollY > range) {
+ newScrollY = range;
+ }
+ if (newScrollY != oldScrollY) {
+ super.scrollTo(mScrollX, newScrollY);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ protected void onOverScrolled(int scrollX, int scrollY,
+ boolean clampedX, boolean clampedY) {
+ // Treat animating scrolls differently; see #computeScroll() for why.
+ if (!mScroller.isFinished()) {
+ mScrollX = scrollX;
+ mScrollY = scrollY;
+ invalidateParentIfNeeded();
+ if (clampedY) {
+ mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
+ }
+ } else {
+ super.scrollTo(scrollX, scrollY);
+ }
+ awakenScrollBars();
+ }
+
+ private int getScrollRange() {
+ int scrollRange = 0;
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ scrollRange = Math.max(0,
+ child.getHeight() - (getHeight() - mPaddingBottom - mPaddingTop));
+ }
+ return scrollRange;
+ }
+
+ /**
+ * <p>
+ * Finds the next focusable component that fits in this View's bounds
+ * (excluding fading edges) pretending that this View's top is located at
+ * the parameter top.
+ * </p>
+ *
+ * @param topFocus look for a candidate at the top of the bounds if topFocus is true,
+ * or at the bottom of the bounds if topFocus is false
+ * @param top the top offset of the bounds in which a focusable must be
+ * found (the fading edge is assumed to start at this position)
+ * @param preferredFocusable the View that has highest priority and will be
+ * returned if it is within my bounds (null is valid)
+ * @return the next focusable component in the bounds or null if none can be found
+ */
+ private View findFocusableViewInMyBounds(final boolean topFocus,
+ final int top, View preferredFocusable) {
+ /*
+ * The fading edge's transparent side should be considered for focus
+ * since it's mostly visible, so we divide the actual fading edge length
+ * by 2.
+ */
+ final int fadingEdgeLength = getVerticalFadingEdgeLength() / 2;
+ final int topWithoutFadingEdge = top + fadingEdgeLength;
+ final int bottomWithoutFadingEdge = top + getHeight() - fadingEdgeLength;
+
+ if ((preferredFocusable != null)
+ && (preferredFocusable.getTop() < bottomWithoutFadingEdge)
+ && (preferredFocusable.getBottom() > topWithoutFadingEdge)) {
+ return preferredFocusable;
+ }
+
+ return findFocusableViewInBounds(topFocus, topWithoutFadingEdge,
+ bottomWithoutFadingEdge);
+ }
+
+ /**
+ * <p>
+ * Finds the next focusable component that fits in the specified bounds.
+ * </p>
+ *
+ * @param topFocus look for a candidate is the one at the top of the bounds
+ * if topFocus is true, or at the bottom of the bounds if topFocus is
+ * false
+ * @param top the top offset of the bounds in which a focusable must be
+ * found
+ * @param bottom the bottom offset of the bounds in which a focusable must
+ * be found
+ * @return the next focusable component in the bounds or null if none can
+ * be found
+ */
+ private View findFocusableViewInBounds(boolean topFocus, int top, int bottom) {
+
+ List<View> focusables = getFocusables(View.FOCUS_FORWARD);
+ View focusCandidate = null;
+
+ /*
+ * A fully contained focusable is one where its top is below the bound's
+ * top, and its bottom is above the bound's bottom. A partially
+ * contained focusable is one where some part of it is within the
+ * bounds, but it also has some part that is not within bounds. A fully contained
+ * focusable is preferred to a partially contained focusable.
+ */
+ boolean foundFullyContainedFocusable = false;
+
+ int count = focusables.size();
+ for (int i = 0; i < count; i++) {
+ View view = focusables.get(i);
+ int viewTop = view.getTop();
+ int viewBottom = view.getBottom();
+
+ if (top < viewBottom && viewTop < bottom) {
+ /*
+ * the focusable is in the target area, it is a candidate for
+ * focusing
+ */
+
+ final boolean viewIsFullyContained = (top < viewTop) &&
+ (viewBottom < bottom);
+
+ if (focusCandidate == null) {
+ /* No candidate, take this one */
+ focusCandidate = view;
+ foundFullyContainedFocusable = viewIsFullyContained;
+ } else {
+ final boolean viewIsCloserToBoundary =
+ (topFocus && viewTop < focusCandidate.getTop()) ||
+ (!topFocus && viewBottom > focusCandidate
+ .getBottom());
+
+ if (foundFullyContainedFocusable) {
+ if (viewIsFullyContained && viewIsCloserToBoundary) {
+ /*
+ * We're dealing with only fully contained views, so
+ * it has to be closer to the boundary to beat our
+ * candidate
+ */
+ focusCandidate = view;
+ }
+ } else {
+ if (viewIsFullyContained) {
+ /* Any fully contained view beats a partially contained view */
+ focusCandidate = view;
+ foundFullyContainedFocusable = true;
+ } else if (viewIsCloserToBoundary) {
+ /*
+ * Partially contained view beats another partially
+ * contained view if it's closer
+ */
+ focusCandidate = view;
+ }
+ }
+ }
+ }
+ }
+
+ return focusCandidate;
+ }
+
+ /**
+ * <p>Handles scrolling in response to a "page up/down" shortcut press. This
+ * method will scroll the view by one page up or down and give the focus
+ * to the topmost/bottommost component in the new visible area. If no
+ * component is a good candidate for focus, this scrollview reclaims the
+ * focus.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+ * to go one page up or
+ * {@link android.view.View#FOCUS_DOWN} to go one page down
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ public boolean pageScroll(int direction) {
+ boolean down = direction == View.FOCUS_DOWN;
+ int height = getHeight();
+
+ if (down) {
+ mTempRect.top = getScrollY() + height;
+ int count = getChildCount();
+ if (count > 0) {
+ View view = getChildAt(count - 1);
+ if (mTempRect.top + height > view.getBottom()) {
+ mTempRect.top = view.getBottom() - height;
+ }
+ }
+ } else {
+ mTempRect.top = getScrollY() - height;
+ if (mTempRect.top < 0) {
+ mTempRect.top = 0;
+ }
+ }
+ mTempRect.bottom = mTempRect.top + height;
+
+ return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom);
+ }
+
+ /**
+ * <p>Handles scrolling in response to a "home/end" shortcut press. This
+ * method will scroll the view to the top or bottom and give the focus
+ * to the topmost/bottommost component in the new visible area. If no
+ * component is a good candidate for focus, this scrollview reclaims the
+ * focus.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+ * to go the top of the view or
+ * {@link android.view.View#FOCUS_DOWN} to go the bottom
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ public boolean fullScroll(int direction) {
+ boolean down = direction == View.FOCUS_DOWN;
+ int height = getHeight();
+
+ mTempRect.top = 0;
+ mTempRect.bottom = height;
+
+ if (down) {
+ int count = getChildCount();
+ if (count > 0) {
+ View view = getChildAt(count - 1);
+ mTempRect.bottom = view.getBottom() + mPaddingBottom;
+ mTempRect.top = mTempRect.bottom - height;
+ }
+ }
+
+ return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom);
+ }
+
+ /**
+ * <p>Scrolls the view to make the area defined by <code>top</code> and
+ * <code>bottom</code> visible. This method attempts to give the focus
+ * to a component visible in this area. If no component can be focused in
+ * the new visible area, the focus is reclaimed by this ScrollView.</p>
+ *
+ * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+ * to go upward, {@link android.view.View#FOCUS_DOWN} to downward
+ * @param top the top offset of the new area to be made visible
+ * @param bottom the bottom offset of the new area to be made visible
+ * @return true if the key event is consumed by this method, false otherwise
+ */
+ private boolean scrollAndFocus(int direction, int top, int bottom) {
+ boolean handled = true;
+
+ int height = getHeight();
+ int containerTop = getScrollY();
+ int containerBottom = containerTop + height;
+ boolean up = direction == View.FOCUS_UP;
+
+ View newFocused = findFocusableViewInBounds(up, top, bottom);
+ if (newFocused == null) {
+ newFocused = this;
+ }
+
+ if (top >= containerTop && bottom <= containerBottom) {
+ handled = false;
+ } else {
+ int delta = up ? (top - containerTop) : (bottom - containerBottom);
+ doScrollY(delta);
+ }
+
+ if (newFocused != findFocus()) newFocused.requestFocus(direction);
+
+ return handled;
+ }
+
+ /**
+ * Handle scrolling in response to an up or down arrow click.
+ *
+ * @param direction The direction corresponding to the arrow key that was
+ * pressed
+ * @return True if we consumed the event, false otherwise
+ */
+ public boolean arrowScroll(int direction) {
+
+ View currentFocused = findFocus();
+ if (currentFocused == this) currentFocused = null;
+
+ View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
+
+ final int maxJump = getMaxScrollAmount();
+
+ if (nextFocused != null && isWithinDeltaOfScreen(nextFocused, maxJump, getHeight())) {
+ nextFocused.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(nextFocused, mTempRect);
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+ doScrollY(scrollDelta);
+ nextFocused.requestFocus(direction);
+ } else {
+ // no new focus
+ int scrollDelta = maxJump;
+
+ if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
+ scrollDelta = getScrollY();
+ } else if (direction == View.FOCUS_DOWN) {
+ if (getChildCount() > 0) {
+ int daBottom = getChildAt(0).getBottom();
+ int screenBottom = getScrollY() + getHeight() - mPaddingBottom;
+ if (daBottom - screenBottom < maxJump) {
+ scrollDelta = daBottom - screenBottom;
+ }
+ }
+ }
+ if (scrollDelta == 0) {
+ return false;
+ }
+ doScrollY(direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta);
+ }
+
+ if (currentFocused != null && currentFocused.isFocused()
+ && isOffScreen(currentFocused)) {
+ // previously focused item still has focus and is off screen, give
+ // it up (take it back to ourselves)
+ // (also, need to temporarily force FOCUS_BEFORE_DESCENDANTS so we are
+ // sure to
+ // get it)
+ final int descendantFocusability = getDescendantFocusability(); // save
+ setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+ requestFocus();
+ setDescendantFocusability(descendantFocusability); // restore
+ }
+ return true;
+ }
+
+ /**
+ * @return whether the descendant of this scroll view is scrolled off
+ * screen.
+ */
+ private boolean isOffScreen(View descendant) {
+ return !isWithinDeltaOfScreen(descendant, 0, getHeight());
+ }
+
+ /**
+ * @return whether the descendant of this scroll view is within delta
+ * pixels of being on the screen.
+ */
+ private boolean isWithinDeltaOfScreen(View descendant, int delta, int height) {
+ descendant.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(descendant, mTempRect);
+
+ return (mTempRect.bottom + delta) >= getScrollY()
+ && (mTempRect.top - delta) <= (getScrollY() + height);
+ }
+
+ /**
+ * Smooth scroll by a Y delta
+ *
+ * @param delta the number of pixels to scroll by on the Y axis
+ */
+ private void doScrollY(int delta) {
+ if (delta != 0) {
+ if (mSmoothScrollingEnabled) {
+ smoothScrollBy(0, delta);
+ } else {
+ scrollBy(0, delta);
+ }
+ }
+ }
+
+ /**
+ * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
+ *
+ * @param dx the number of pixels to scroll by on the X axis
+ * @param dy the number of pixels to scroll by on the Y axis
+ */
+ public final void smoothScrollBy(int dx, int dy) {
+ if (getChildCount() == 0) {
+ // Nothing to do.
+ return;
+ }
+ long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
+ if (duration > ANIMATED_SCROLL_GAP) {
+ final int height = getHeight() - mPaddingBottom - mPaddingTop;
+ final int bottom = getChildAt(0).getHeight();
+ final int maxY = Math.max(0, bottom - height);
+ final int scrollY = mScrollY;
+ dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
+
+ mScroller.startScroll(mScrollX, scrollY, 0, dy);
+ invalidate();
+ } else {
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
+ }
+ scrollBy(dx, dy);
+ }
+ mLastScroll = AnimationUtils.currentAnimationTimeMillis();
+ }
+
+ /**
+ * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
+ *
+ * @param x the position where to scroll on the X axis
+ * @param y the position where to scroll on the Y axis
+ */
+ public final void smoothScrollTo(int x, int y) {
+ smoothScrollBy(x - mScrollX, y - mScrollY);
+ }
+
+ /**
+ * <p>The scroll range of a scroll view is the overall height of all of its
+ * children.</p>
+ */
+ @Override
+ protected int computeVerticalScrollRange() {
+ final int count = getChildCount();
+ final int contentHeight = getHeight() - mPaddingBottom - mPaddingTop;
+ if (count == 0) {
+ return contentHeight;
+ }
+
+ int scrollRange = getChildAt(0).getBottom();
+ final int scrollY = mScrollY;
+ final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
+ if (scrollY < 0) {
+ scrollRange -= scrollY;
+ } else if (scrollY > overscrollBottom) {
+ scrollRange += scrollY - overscrollBottom;
+ }
+
+ return scrollRange;
+ }
+
+ @Override
+ protected int computeVerticalScrollOffset() {
+ return Math.max(0, super.computeVerticalScrollOffset());
+ }
+
+ @Override
+ protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
+ ViewGroup.LayoutParams lp = child.getLayoutParams();
+
+ int childWidthMeasureSpec;
+ int childHeightMeasureSpec;
+
+ childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, mPaddingLeft
+ + mPaddingRight, lp.width);
+
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ @Override
+ protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
+ int parentHeightMeasureSpec, int heightUsed) {
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
+ mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ + widthUsed, lp.width);
+ final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ @Override
+ public void computeScroll() {
+ if (mScroller.computeScrollOffset()) {
+ // This is called at drawing time by ViewGroup. We don't want to
+ // re-show the scrollbars at this point, which scrollTo will do,
+ // so we replicate most of scrollTo here.
+ //
+ // It's a little odd to call onScrollChanged from inside the drawing.
+ //
+ // It is, except when you remember that computeScroll() is used to
+ // animate scrolling. So unless we want to defer the onScrollChanged()
+ // until the end of the animated scrolling, we don't really have a
+ // choice here.
+ //
+ // I agree. The alternative, which I think would be worse, is to post
+ // something and tell the subclasses later. This is bad because there
+ // will be a window where mScrollX/Y is different from what the app
+ // thinks it is.
+ //
+ int oldX = mScrollX;
+ int oldY = mScrollY;
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+
+ if (oldX != x || oldY != y) {
+ overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, getScrollRange(),
+ 0, mOverflingDistance, false);
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+
+ final int range = getScrollRange();
+ final int overscrollMode = getOverScrollMode();
+ if (overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
+ if (y < 0 && oldY >= 0) {
+ mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity());
+ } else if (y > range && oldY <= range) {
+ mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity());
+ }
+ }
+ }
+ awakenScrollBars();
+
+ // Keep on drawing until the animation has finished.
+ postInvalidate();
+ } else {
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
+ }
+ }
+
+ /**
+ * Scrolls the view to the given child.
+ *
+ * @param child the View to scroll to
+ */
+ private void scrollToChild(View child) {
+ child.getDrawingRect(mTempRect);
+
+ /* Offset from child's local coordinates to ScrollView coordinates */
+ offsetDescendantRectToMyCoords(child, mTempRect);
+
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+
+ if (scrollDelta != 0) {
+ scrollBy(0, scrollDelta);
+ }
+ }
+
+ /**
+ * If rect is off screen, scroll just enough to get it (or at least the
+ * first screen size chunk of it) on screen.
+ *
+ * @param rect The rectangle.
+ * @param immediate True to scroll immediately without animation
+ * @return true if scrolling was performed
+ */
+ private boolean scrollToChildRect(Rect rect, boolean immediate) {
+ final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
+ final boolean scroll = delta != 0;
+ if (scroll) {
+ if (immediate) {
+ scrollBy(0, delta);
+ } else {
+ smoothScrollBy(0, delta);
+ }
+ }
+ return scroll;
+ }
+
+ /**
+ * Compute the amount to scroll in the Y direction in order to get
+ * a rectangle completely on the screen (or, if taller than the screen,
+ * at least the first screen size chunk of it).
+ *
+ * @param rect The rect.
+ * @return The scroll delta.
+ */
+ protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
+ if (getChildCount() == 0) return 0;
+
+ int height = getHeight();
+ int screenTop = getScrollY();
+ int screenBottom = screenTop + height;
+
+ int fadingEdge = getVerticalFadingEdgeLength();
+
+ // leave room for top fading edge as long as rect isn't at very top
+ if (rect.top > 0) {
+ screenTop += fadingEdge;
+ }
+
+ // leave room for bottom fading edge as long as rect isn't at very bottom
+ if (rect.bottom < getChildAt(0).getHeight()) {
+ screenBottom -= fadingEdge;
+ }
+
+ int scrollYDelta = 0;
+
+ if (rect.bottom > screenBottom && rect.top > screenTop) {
+ // need to move down to get it in view: move down just enough so
+ // that the entire rectangle is in view (or at least the first
+ // screen size chunk).
+
+ if (rect.height() > height) {
+ // just enough to get screen size chunk on
+ scrollYDelta += (rect.top - screenTop);
+ } else {
+ // get entire rect at bottom of screen
+ scrollYDelta += (rect.bottom - screenBottom);
+ }
+
+ // make sure we aren't scrolling beyond the end of our content
+ int bottom = getChildAt(0).getBottom();
+ int distanceToBottom = bottom - screenBottom;
+ scrollYDelta = Math.min(scrollYDelta, distanceToBottom);
+
+ } else if (rect.top < screenTop && rect.bottom < screenBottom) {
+ // need to move up to get it in view: move up just enough so that
+ // entire rectangle is in view (or at least the first screen
+ // size chunk of it).
+
+ if (rect.height() > height) {
+ // screen size chunk
+ scrollYDelta -= (screenBottom - rect.bottom);
+ } else {
+ // entire rect at top
+ scrollYDelta -= (screenTop - rect.top);
+ }
+
+ // make sure we aren't scrolling any further than the top our content
+ scrollYDelta = Math.max(scrollYDelta, -getScrollY());
+ }
+ return scrollYDelta;
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ if (!mIsLayoutDirty) {
+ scrollToChild(focused);
+ } else {
+ // The child may not be laid out yet, we can't compute the scroll yet
+ mChildToScrollTo = focused;
+ }
+ super.requestChildFocus(child, focused);
+ }
+
+
+ /**
+ * When looking for focus in children of a scroll view, need to be a little
+ * more careful not to give focus to something that is scrolled off screen.
+ *
+ * This is more expensive than the default {@link android.view.ViewGroup}
+ * implementation, otherwise this behavior might have been made the default.
+ */
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction,
+ Rect previouslyFocusedRect) {
+
+ // convert from forward / backward notation to up / down / left / right
+ // (ugh).
+ if (direction == View.FOCUS_FORWARD) {
+ direction = View.FOCUS_DOWN;
+ } else if (direction == View.FOCUS_BACKWARD) {
+ direction = View.FOCUS_UP;
+ }
+
+ final View nextFocus = previouslyFocusedRect == null ?
+ FocusFinder.getInstance().findNextFocus(this, null, direction) :
+ FocusFinder.getInstance().findNextFocusFromRect(this,
+ previouslyFocusedRect, direction);
+
+ if (nextFocus == null) {
+ return false;
+ }
+
+ if (isOffScreen(nextFocus)) {
+ return false;
+ }
+
+ return nextFocus.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ @Override
+ public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
+ boolean immediate) {
+ // offset into coordinate space of this scroll view
+ rectangle.offset(child.getLeft() - child.getScrollX(),
+ child.getTop() - child.getScrollY());
+
+ return scrollToChildRect(rectangle, immediate);
+ }
+
+ @Override
+ public void requestLayout() {
+ mIsLayoutDirty = true;
+ super.requestLayout();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
+ }
+ if (mFlingStrictSpan != null) {
+ mFlingStrictSpan.finish();
+ mFlingStrictSpan = null;
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ mIsLayoutDirty = false;
+ // Give a child focus if it needs it
+ if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
+ scrollToChild(mChildToScrollTo);
+ }
+ mChildToScrollTo = null;
+
+ // Calling this with the present values causes it to re-clam them
+ scrollTo(mScrollX, mScrollY);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ View currentFocused = findFocus();
+ if (null == currentFocused || this == currentFocused)
+ return;
+
+ // If the currently-focused view was visible on the screen when the
+ // screen was at the old height, then scroll the screen to make that
+ // view visible with the new screen height.
+ if (isWithinDeltaOfScreen(currentFocused, 0, oldh)) {
+ currentFocused.getDrawingRect(mTempRect);
+ offsetDescendantRectToMyCoords(currentFocused, mTempRect);
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+ doScrollY(scrollDelta);
+ }
+ }
+
+ /**
+ * Return true if child is an descendant of parent, (or equal to the parent).
+ */
+ private boolean isViewDescendantOf(View child, View parent) {
+ if (child == parent) {
+ return true;
+ }
+
+ final ViewParent theParent = child.getParent();
+ return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
+ }
+
+ /**
+ * Fling the scroll view
+ *
+ * @param velocityY The initial velocity in the Y direction. Positive
+ * numbers mean that the finger/cursor is moving down the screen,
+ * which means we want to scroll towards the top.
+ */
+ public void fling(int velocityY) {
+ if (getChildCount() > 0) {
+ int height = getHeight() - mPaddingBottom - mPaddingTop;
+ int bottom = getChildAt(0).getHeight();
+
+ mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
+ Math.max(0, bottom - height), 0, height/2);
+
+ final boolean movingDown = velocityY > 0;
+
+ View currentFocused = findFocus();
+ View newFocused =
+ findFocusableViewInMyBounds(movingDown, mScroller.getFinalY(), currentFocused);
+ if (newFocused == null) {
+ newFocused = this;
+ }
+
+ if (newFocused != currentFocused) {
+ newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP);
+ }
+
+ if (mFlingStrictSpan == null) {
+ mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
+ }
+
+ invalidate();
+ }
+ }
+
+ private void endDrag() {
+ mIsBeingDragged = false;
+
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
+ }
+
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>This version also clamps the scrolling to the bounds of our child.
+ */
+ @Override
+ public void scrollTo(int x, int y) {
+ // we rely on the fact the View.scrollBy calls scrollTo.
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ x = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
+ y = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
+ if (x != mScrollX || y != mScrollY) {
+ super.scrollTo(x, y);
+ }
+ }
+ }
+
+ @Override
+ public void setOverScrollMode(int mode) {
+ if (mode != OVER_SCROLL_NEVER) {
+ if (mEdgeGlowTop == null) {
+ Context context = getContext();
+ final Resources res = context.getResources();
+ final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
+ final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
+ mEdgeGlowTop = new EdgeGlow(context, edge, glow);
+ mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
+ }
+ } else {
+ mEdgeGlowTop = null;
+ mEdgeGlowBottom = null;
+ }
+ super.setOverScrollMode(mode);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ if (mEdgeGlowTop != null) {
+ final int scrollY = mScrollY;
+ if (!mEdgeGlowTop.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int width = getWidth() - mPaddingLeft - mPaddingRight;
+
+ canvas.translate(mPaddingLeft, Math.min(0, scrollY));
+ mEdgeGlowTop.setSize(width, getHeight());
+ if (mEdgeGlowTop.draw(canvas)) {
+ invalidate();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ if (!mEdgeGlowBottom.isFinished()) {
+ final int restoreCount = canvas.save();
+ final int width = getWidth() - mPaddingLeft - mPaddingRight;
+ final int height = getHeight();
+
+ canvas.translate(-width + mPaddingLeft,
+ Math.max(getScrollRange(), scrollY) + height);
+ canvas.rotate(180, width, 0);
+ mEdgeGlowBottom.setSize(width, height);
+ if (mEdgeGlowBottom.draw(canvas)) {
+ invalidate();
+ }
+ canvas.restoreToCount(restoreCount);
+ }
+ }
+ }
+
+ private int clamp(int n, int my, int child) {
+ if (my >= child || n < 0) {
+ /* my >= child is this case:
+ * |--------------- me ---------------|
+ * |------ child ------|
+ * or
+ * |--------------- me ---------------|
+ * |------ child ------|
+ * or
+ * |--------------- me ---------------|
+ * |------ child ------|
+ *
+ * n < 0 is this case:
+ * |------ me ------|
+ * |-------- child --------|
+ * |-- mScrollX --|
+ */
+ return 0;
+ }
+ if ((my+n) > child) {
+ /* this case:
+ * |------ me ------|
+ * |------ child ------|
+ * |-- mScrollX --|
+ */
+ return child-my;
+ }
+ return n;
+ }
+}
diff --git a/src/com/android/browser/view/StopProgressView.java b/src/com/android/browser/view/StopProgressView.java
new file mode 100644
index 0000000..64fa5d0
--- /dev/null
+++ b/src/com/android/browser/view/StopProgressView.java
@@ -0,0 +1,98 @@
+
+package com.android.browser.view;
+
+import com.android.browser.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.ProgressBar;
+
+
+public class StopProgressView extends ProgressBar {
+
+ Drawable mOverlayDrawable;
+ Drawable mProgressDrawable;
+ int mWidth;
+ int mHeight;
+
+ /**
+ * @param context
+ * @param attrs
+ * @param defStyle
+ * @param styleRes
+ */
+ public StopProgressView(Context context, AttributeSet attrs, int defStyle, int styleRes) {
+ super(context, attrs, defStyle, styleRes);
+ init(attrs);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ * @param defStyle
+ */
+ public StopProgressView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public StopProgressView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ }
+
+ /**
+ * @param context
+ */
+ public StopProgressView(Context context) {
+ super(context);
+ init(null);
+ }
+
+ private void init(AttributeSet attrs) {
+ mProgressDrawable = getIndeterminateDrawable();
+ setImageDrawable(mContext.getResources()
+ .getDrawable(R.drawable.ic_stop_holo_dark));
+ }
+
+ public void hideProgress() {
+ setIndeterminateDrawable(null);
+ }
+
+ public void showProgress() {
+ setIndeterminateDrawable(mProgressDrawable);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mWidth = (right - left) * 2 / 3;
+ mHeight = (bottom - top) * 2 / 3;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (mOverlayDrawable != null) {
+ int l = (getWidth() - mWidth) / 2;
+ int t = (getHeight() - mHeight) / 2;
+ mOverlayDrawable.setBounds(l, t, l + mWidth, t + mHeight);
+ mOverlayDrawable.draw(canvas);
+ }
+ }
+
+ public Drawable getDrawable() {
+ return mOverlayDrawable;
+ }
+
+ public void setImageDrawable(Drawable d) {
+ mOverlayDrawable = d;
+ }
+
+}
diff --git a/src/com/android/browser/widget/BookmarkThumbnailWidgetProvider.java b/src/com/android/browser/widget/BookmarkThumbnailWidgetProvider.java
index 48d7123..f3d2675 100644
--- a/src/com/android/browser/widget/BookmarkThumbnailWidgetProvider.java
+++ b/src/com/android/browser/widget/BookmarkThumbnailWidgetProvider.java
@@ -16,9 +16,6 @@
package com.android.browser.widget;
-import com.android.browser.BrowserActivity;
-import com.android.browser.R;
-
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
@@ -28,6 +25,9 @@
import android.net.Uri;
import android.widget.RemoteViews;
+import com.android.browser.BrowserActivity;
+import com.android.browser.R;
+
/**
* Widget that shows a preview of the user's bookmarks.
*/
@@ -91,7 +91,7 @@
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.bookmarkthumbnailwidget);
views.setOnClickPendingIntent(R.id.app_shortcut, launchBrowser);
- views.setRemoteAdapter(appWidgetId, R.id.bookmarks_list, updateIntent);
+ views.setRemoteAdapter(R.id.bookmarks_list, updateIntent);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.bookmarks_list);
Intent ic = new Intent(context, BookmarkWidgetProxy.class);
views.setPendingIntentTemplate(R.id.bookmarks_list,
@@ -110,27 +110,9 @@
}
public static void refreshWidgets(Context context) {
- refreshWidgets(context, false);
+ context.sendBroadcast(new Intent(
+ BookmarkThumbnailWidgetProvider.ACTION_BOOKMARK_APPWIDGET_UPDATE,
+ null, context, BookmarkThumbnailWidgetProvider.class));
}
- public static void refreshWidgets(Context context, boolean zeroState) {
- if (zeroState) {
- final Context appContext = context.getApplicationContext();
- new Thread() {
- @Override
- public void run() {
- AppWidgetManager wm = AppWidgetManager.getInstance(appContext);
- int[] ids = wm.getAppWidgetIds(getComponentName(appContext));
- for (int id : ids) {
- BookmarkThumbnailWidgetService.clearWidgetState(appContext, id);
- }
- refreshWidgets(appContext, false);
- }
- }.start();
- } else {
- context.sendBroadcast(new Intent(
- BookmarkThumbnailWidgetProvider.ACTION_BOOKMARK_APPWIDGET_UPDATE,
- null, context, BookmarkThumbnailWidgetProvider.class));
- }
- }
}
diff --git a/src/com/android/browser/widget/BookmarkThumbnailWidgetService.java b/src/com/android/browser/widget/BookmarkThumbnailWidgetService.java
index 675cdd9..7d174ee 100644
--- a/src/com/android/browser/widget/BookmarkThumbnailWidgetService.java
+++ b/src/com/android/browser/widget/BookmarkThumbnailWidgetService.java
@@ -16,10 +16,6 @@
package com.android.browser.widget;
-import com.android.browser.BookmarkUtils;
-import com.android.browser.BrowserActivity;
-import com.android.browser.R;
-
import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
@@ -40,9 +36,12 @@
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
+import com.android.browser.BrowserActivity;
+import com.android.browser.R;
+import com.android.browser.provider.BrowserProvider2;
+
import java.io.File;
import java.io.FilenameFilter;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -110,11 +109,11 @@
}
}
- static void clearWidgetState(Context context, int widgetId) {
+ static void setupWidgetState(Context context, int widgetId, long rootFolder) {
SharedPreferences pref = getWidgetState(context, widgetId);
pref.edit()
- .remove(STATE_CURRENT_FOLDER)
- .remove(STATE_ROOT_FOLDER)
+ .putLong(STATE_CURRENT_FOLDER, rootFolder)
+ .putLong(STATE_ROOT_FOLDER, rootFolder)
.commit();
}
@@ -311,8 +310,8 @@
long token = Binder.clearCallingIdentity();
syncState();
if (mRootFolder < 0 || mCurrentFolder < 0) {
- // Our state has been zero'd, reset (account change most likely)
- mRootFolder = getRootFolder();
+ // This shouldn't happen, but JIC default to the local account
+ mRootFolder = BrowserProvider2.FIXED_ID_ROOT;
mCurrentFolder = mRootFolder;
saveState();
}
@@ -327,27 +326,12 @@
}
}
- long getRootFolder() {
- Uri uri = Uri.withAppendedPath(
- BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, "id");
- uri = BookmarkUtils.addAccountInfo(mContext, uri.buildUpon()).build();
- Cursor c = mContext.getContentResolver().query(
- uri, null, null, null, null);
- try {
- c.moveToFirst();
- return c.getLong(0);
- } finally {
- c.close();
- }
- }
-
void loadBookmarks() {
resetBookmarks();
Uri uri = ContentUris.withAppendedId(
BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER,
mCurrentFolder);
- uri = BookmarkUtils.addAccountInfo(mContext, uri.buildUpon()).build();
mBookmarks = mContext.getContentResolver().query(uri, PROJECTION,
null, null, null);
if (mCurrentFolder != mRootFolder) {
diff --git a/src/com/android/browser/widget/BookmarkWidgetConfigure.java b/src/com/android/browser/widget/BookmarkWidgetConfigure.java
new file mode 100644
index 0000000..4231f37
--- /dev/null
+++ b/src/com/android/browser/widget/BookmarkWidgetConfigure.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 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.widget;
+
+import android.app.ListActivity;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.content.Loader;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.android.browser.AddBookmarkPage.AccountsLoader;
+import com.android.browser.AddBookmarkPage.BookmarkAccount;
+import com.android.browser.R;
+import com.android.browser.provider.BrowserProvider2;
+
+public class BookmarkWidgetConfigure extends ListActivity
+ implements OnClickListener, LoaderCallbacks<Cursor> {
+
+ static final int LOADER_ACCOUNTS = 1;
+
+ private ArrayAdapter<BookmarkAccount> mAccountAdapter;
+ private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setResult(RESULT_CANCELED);
+ setVisible(false);
+ setContentView(R.layout.widget_account_selection);
+ findViewById(R.id.cancel).setOnClickListener(this);
+ mAccountAdapter = new ArrayAdapter<BookmarkAccount>(this,
+ android.R.layout.simple_list_item_1);
+ setListAdapter(mAccountAdapter);
+ Intent intent = getIntent();
+ Bundle extras = intent.getExtras();
+ if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+ if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ finish();
+ } else {
+ getLoaderManager().initLoader(LOADER_ACCOUNTS, null, this);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ BookmarkAccount account = mAccountAdapter.getItem(position);
+ pickAccount(account.rootFolderId);
+ }
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ return new AccountsLoader(this);
+ }
+
+ void pickAccount(long rootId) {
+ BookmarkThumbnailWidgetService.setupWidgetState(this, mAppWidgetId, rootId);
+ Intent result = new Intent();
+ result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+ setResult(RESULT_OK, result);
+ finish();
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+ if (cursor == null || cursor.getCount() <= 1) {
+ // We always have the local account, so if count == 1 it must
+ // be the local account
+ pickAccount(BrowserProvider2.FIXED_ID_ROOT);
+ } else {
+ mAccountAdapter.clear();
+ while (cursor.moveToNext()) {
+ mAccountAdapter.add(new BookmarkAccount(this, cursor));
+ }
+ setVisible(true);
+ }
+ getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ // Don't care
+ }
+
+}
diff --git a/tests/src/com/android/browser/BrowserProviderTests.java b/tests/src/com/android/browser/BrowserProviderTests.java
index eb8ba80..c63cad1 100644
--- a/tests/src/com/android/browser/BrowserProviderTests.java
+++ b/tests/src/com/android/browser/BrowserProviderTests.java
@@ -16,6 +16,7 @@
package com.android.browser;
+import com.android.browser.provider.BrowserProvider;
import com.android.browser.provider.BrowserProvider2;
import com.android.browser.tests.utils.ProviderTestCase3;
diff --git a/tests/src/com/android/browser/PopularUrlsTest.java b/tests/src/com/android/browser/PopularUrlsTest.java
index 3e7515f..a635f0b 100644
--- a/tests/src/com/android/browser/PopularUrlsTest.java
+++ b/tests/src/com/android/browser/PopularUrlsTest.java
@@ -77,6 +77,7 @@
super.setUp();
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("about:blank"));
+ i.putExtra(Controller.NO_CRASH_RECOVERY, true);
setActivityIntent(i);
mActivity = getActivity();
mController = mActivity.getController();
diff --git a/tests/src/com/android/browser/TestWebChromeClient.java b/tests/src/com/android/browser/TestWebChromeClient.java
index 53f8db3..dd84b3a 100644
--- a/tests/src/com/android/browser/TestWebChromeClient.java
+++ b/tests/src/com/android/browser/TestWebChromeClient.java
@@ -84,7 +84,9 @@
@Override
public boolean onCreateWindow(WebView view, boolean dialog,
boolean userGesture, Message resultMsg) {
- return mWrappedClient.onCreateWindow(view, dialog, userGesture, resultMsg);
+ // do not open any new pop-ups
+ resultMsg.sendToTarget();
+ return true;
}
/** {@inheritDoc} */